Changes
80 changed files (+4188/-4176)
-
-
@@ -8,13 +8,13 @@section matrices -- Adding vectors #eval !![1, 2] + !![3, 4] -- !![4, 6] #eval ![1, 2] + ![3, 4] -- ![4, 6] -- Adding matrices #eval !![1, 2; 3, 4] + !![3, 4; 5, 6] -- !![4, 6; 8, 10] -- Multiplying matrices #eval !![1, 2; 3, 4] * !![3, 4; 5, 6] -- !![4, 6; 8, 10] #eval !![1, 2; 3, 4] * !![3, 4; 5, 6] -- !![13, 16; 29, 36] open Matrix
-
-
-
@@ -1,4 +1,4 @@# Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. config: 52b95d1cbc5ae4f410fd1f171141e2ae # This file records the configuration used when building these files. When it is not found, a full rebuild will be done. config: 5f7d574404b36ea843014084d74003d7 tags: 645f666f9bcd5a90fca523b33c5a78b7
-
-
-
@@ -1,3 +1,5 @@<!DOCTYPE html> <html class="writer-html5" lang="en" data-content_root="./"> <head>
-
@@ -6,17 +8,16 @@<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>1. Introduction — Mathematics in Lean 0.1 documentation</title> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=80d5e7a1" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=86f27845" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" /> <link rel="stylesheet" type="text/css" href="_static/css/custom.css?v=0731ccc3" /> <link rel="shortcut icon" href="_static/favicon.ico"/> <script src="_static/jquery.js?v=8dae8fb0"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=888ff710"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script src="_static/jquery.js?v=5d32c60e"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=9bcbadda"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script src="_static/js/theme.js"></script> <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" />
-
@@ -159,7 +160,7 @@ which is why we suggested making a copy.)</p><p>We intend for you to work on the exercises in the <code class="docutils literal notranslate"><span class="pre">MIL</span></code> folder while reading the textbook, which contains explanations, instructions, and hints. The text will often include examples, like this one:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#eval</span> <span class="s2">"Hello, World!"</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#eval</span><span class="w"> </span><span class="s2">"Hello, World!"</span> </pre></div> </div> <p>You should be able to find the corresponding example in the associated
-
@@ -186,35 +187,35 @@ <p id="index-0">Every expression has a <em>type</em>, and you can use the <cite>#check</cite> command toprint it. Some expressions have types like <cite>ℕ</cite> or <cite>ℕ → ℕ</cite>. These are mathematical objects.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="mi">2</span> <span class="bp">+</span> <span class="mi">2</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">2</span> <span class="kd">def</span> <span class="n">f</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:=</span> <span class="n">x</span> <span class="bp">+</span> <span class="mi">3</span> <span class="kd">def</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">3</span> <span class="k">#check</span> <span class="n">f</span> <span class="k">#check</span><span class="w"> </span><span class="n">f</span> </pre></div> </div> <p>Some expressions have type <cite>Prop</cite>. These are mathematical statements.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="mi">2</span> <span class="bp">+</span> <span class="mi">2</span> <span class="bp">=</span> <span class="mi">4</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">4</span> <span class="kd">def</span> <span class="n">FermatLastTheorem</span> <span class="o">:=</span> <span class="bp">∀</span> <span class="n">x</span> <span class="n">y</span> <span class="n">z</span> <span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">,</span> <span class="n">n</span> <span class="bp">></span> <span class="mi">2</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp">*</span> <span class="n">y</span> <span class="bp">*</span> <span class="n">z</span> <span class="bp">≠</span> <span class="mi">0</span> <span class="bp">→</span> <span class="n">x</span> <span class="bp">^</span> <span class="n">n</span> <span class="bp">+</span> <span class="n">y</span> <span class="bp">^</span> <span class="n">n</span> <span class="bp">≠</span> <span class="n">z</span> <span class="bp">^</span> <span class="n">n</span> <span class="kd">def</span><span class="w"> </span><span class="n">FermatLastTheorem</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">,</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="n">n</span> <span class="k">#check</span> <span class="n">FermatLastTheorem</span> <span class="k">#check</span><span class="w"> </span><span class="n">FermatLastTheorem</span> </pre></div> </div> <p>Some expressions have a type, <cite>P</cite>, where <cite>P</cite> itself has type <cite>Prop</cite>. Such an expression is a proof of the proposition <cite>P</cite>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">easy</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">+</span> <span class="mi">2</span> <span class="bp">=</span> <span class="mi">4</span> <span class="o">:=</span> <span class="n">rfl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">easy</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="k">#check</span> <span class="n">easy</span> <span class="k">#check</span><span class="w"> </span><span class="n">easy</span> <span class="kd">theorem</span> <span class="n">hard</span> <span class="o">:</span> <span class="n">FermatLastTheorem</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">hard</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FermatLastTheorem</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> <span class="k">#check</span> <span class="n">hard</span> <span class="k">#check</span><span class="w"> </span><span class="n">hard</span> </pre></div> </div> <p>If you manage to construct an expression of type <code class="docutils literal notranslate"><span class="pre">FermatLastTheorem</span></code> and
-
@@ -243,27 +244,27 @@ (that is, suitable text descriptions thereof),or we can provide Lean with <em>instructions</em> as to how to construct them. For example, the following expression represents a proof of the fact that if <code class="docutils literal notranslate"><span class="pre">n</span></code> is even then so is <code class="docutils literal notranslate"><span class="pre">m</span> <span class="pre">*</span> <span class="pre">n</span></code>:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">m</span> <span class="n">n</span> <span class="o">:</span> <span class="n">Nat</span><span class="o">,</span> <span class="n">Even</span> <span class="n">n</span> <span class="bp">→</span> <span class="n">Even</span> <span class="o">(</span><span class="n">m</span> <span class="bp">*</span> <span class="n">n</span><span class="o">)</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">m</span> <span class="n">n</span> <span class="o">⟨</span><span class="n">k</span><span class="o">,</span> <span class="o">(</span><span class="n">hk</span> <span class="o">:</span> <span class="n">n</span> <span class="bp">=</span> <span class="n">k</span> <span class="bp">+</span> <span class="n">k</span><span class="o">)⟩</span> <span class="bp">↦</span> <span class="k">have</span> <span class="n">hmn</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">*</span> <span class="n">n</span> <span class="bp">=</span> <span class="n">m</span> <span class="bp">*</span> <span class="n">k</span> <span class="bp">+</span> <span class="n">m</span> <span class="bp">*</span> <span class="n">k</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">hk</span><span class="o">,</span> <span class="n">mul_add</span><span class="o">]</span> <span class="k">show</span> <span class="bp">∃</span> <span class="n">l</span><span class="o">,</span> <span class="n">m</span> <span class="bp">*</span> <span class="n">n</span> <span class="bp">=</span> <span class="n">l</span> <span class="bp">+</span> <span class="n">l</span> <span class="k">from</span> <span class="o">⟨</span><span class="n">_</span><span class="o">,</span> <span class="n">hmn</span><span class="o">⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat</span><span class="o">,</span><span class="w"> </span><span class="n">Even</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Even</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">⟨</span><span class="n">k</span><span class="o">,</span><span class="w"> </span><span class="o">(</span><span class="n">hk</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">k</span><span class="o">)⟩</span><span class="w"> </span><span class="bp">↦</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">hmn</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">hk</span><span class="o">,</span><span class="w"> </span><span class="n">mul_add</span><span class="o">]</span> <span class="w"> </span><span class="k">show</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">l</span><span class="o">,</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">l</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">l</span><span class="w"> </span><span class="k">from</span><span class="w"> </span><span class="o">⟨</span><span class="n">_</span><span class="o">,</span><span class="w"> </span><span class="n">hmn</span><span class="o">⟩</span> </pre></div> </div> <p>The <em>proof term</em> can be compressed to a single line:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">m</span> <span class="n">n</span> <span class="o">:</span> <span class="n">Nat</span><span class="o">,</span> <span class="n">Even</span> <span class="n">n</span> <span class="bp">→</span> <span class="n">Even</span> <span class="o">(</span><span class="n">m</span> <span class="bp">*</span> <span class="n">n</span><span class="o">)</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">m</span> <span class="n">n</span> <span class="o">⟨</span><span class="n">k</span><span class="o">,</span> <span class="n">hk</span><span class="o">⟩</span> <span class="bp">↦</span> <span class="o">⟨</span><span class="n">m</span> <span class="bp">*</span> <span class="n">k</span><span class="o">,</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">hk</span><span class="o">,</span> <span class="n">mul_add</span><span class="o">]⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat</span><span class="o">,</span><span class="w"> </span><span class="n">Even</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Even</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="k">fun</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">⟨</span><span class="n">k</span><span class="o">,</span><span class="w"> </span><span class="n">hk</span><span class="o">⟩</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">⟨</span><span class="n">m</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">k</span><span class="o">,</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">hk</span><span class="o">,</span><span class="w"> </span><span class="n">mul_add</span><span class="o">]⟩</span> </pre></div> </div> <p>The following is, instead, a <em>tactic-style</em> proof of the same theorem, where lines starting with <code class="docutils literal notranslate"><span class="pre">--</span></code> are comments, hence ignored by Lean:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">m</span> <span class="n">n</span> <span class="o">:</span> <span class="n">Nat</span><span class="o">,</span> <span class="n">Even</span> <span class="n">n</span> <span class="bp">→</span> <span class="n">Even</span> <span class="o">(</span><span class="n">m</span> <span class="bp">*</span> <span class="n">n</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="c1">-- Say `m` and `n` are natural numbers, and assume `n = 2 * k`.</span> <span class="n">rintro</span> <span class="n">m</span> <span class="n">n</span> <span class="o">⟨</span><span class="n">k</span><span class="o">,</span> <span class="n">hk</span><span class="o">⟩</span> <span class="c1">-- We need to prove `m * n` is twice a natural number. Let's show it's twice `m * k`.</span> <span class="n">use</span> <span class="n">m</span> <span class="bp">*</span> <span class="n">k</span> <span class="c1">-- Substitute for `n`,</span> <span class="n">rw</span> <span class="o">[</span><span class="n">hk</span><span class="o">]</span> <span class="c1">-- and now it's obvious.</span> <span class="n">ring</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat</span><span class="o">,</span><span class="w"> </span><span class="n">Even</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Even</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="c1">-- Say `m` and `n` are natural numbers, and assume `n = 2 * k`.</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">⟨</span><span class="n">k</span><span class="o">,</span><span class="w"> </span><span class="n">hk</span><span class="o">⟩</span> <span class="w"> </span><span class="c1">-- We need to prove `m * n` is twice a natural number. Let's show it's twice `m * k`.</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">k</span> <span class="w"> </span><span class="c1">-- Substitute for `n`,</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">hk</span><span class="o">]</span> <span class="w"> </span><span class="c1">-- and now it's obvious.</span> <span class="w"> </span><span class="n">ring</span> </pre></div> </div> <p>As you enter each line of such a proof in VS Code,
-
@@ -295,8 +296,8 @@ We will also see that, conversely,it is often useful to insert a short proof term in the middle of a tactic proof. That said, in this book, our emphasis will be on the use of tactics.</p> <p>In our example, the tactic proof can also be reduced to a one-liner:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">m</span> <span class="n">n</span> <span class="o">:</span> <span class="n">Nat</span><span class="o">,</span> <span class="n">Even</span> <span class="n">n</span> <span class="bp">→</span> <span class="n">Even</span> <span class="o">(</span><span class="n">m</span> <span class="bp">*</span> <span class="n">n</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rintro</span> <span class="n">m</span> <span class="n">n</span> <span class="o">⟨</span><span class="n">k</span><span class="o">,</span> <span class="n">hk</span><span class="o">⟩</span><span class="bp">;</span> <span class="n">use</span> <span class="n">m</span> <span class="bp">*</span> <span class="n">k</span><span class="bp">;</span> <span class="n">rw</span> <span class="o">[</span><span class="n">hk</span><span class="o">]</span><span class="bp">;</span> <span class="n">ring</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat</span><span class="o">,</span><span class="w"> </span><span class="n">Even</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Even</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">⟨</span><span class="n">k</span><span class="o">,</span><span class="w"> </span><span class="n">hk</span><span class="o">⟩</span><span class="bp">;</span><span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">k</span><span class="bp">;</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">hk</span><span class="o">]</span><span class="bp">;</span><span class="w"> </span><span class="n">ring</span> </pre></div> </div> <p>Here we have used tactics to carry out small proof steps.
-
@@ -305,8 +306,8 @@ and justify longer calculations and bigger inferential steps.For example, we can invoke Lean’s simplifier with specific rules for simplifying statements about parity to prove our theorem automatically.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">m</span> <span class="n">n</span> <span class="o">:</span> <span class="n">Nat</span><span class="o">,</span> <span class="n">Even</span> <span class="n">n</span> <span class="bp">→</span> <span class="n">Even</span> <span class="o">(</span><span class="n">m</span> <span class="bp">*</span> <span class="n">n</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intros</span><span class="bp">;</span> <span class="n">simp</span> <span class="o">[</span><span class="bp">*</span><span class="o">,</span> <span class="n">parity_simps</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat</span><span class="o">,</span><span class="w"> </span><span class="n">Even</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Even</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intros</span><span class="bp">;</span><span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="bp">*</span><span class="o">,</span><span class="w"> </span><span class="n">parity_simps</span><span class="o">]</span> </pre></div> </div> <p>Another big difference between the two introductions is that
-
-
-
@@ -1,3 +1,5 @@<!DOCTYPE html> <html class="writer-html5" lang="en" data-content_root="./"> <head>
-
@@ -6,18 +8,17 @@<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>2. Basics — Mathematics in Lean 0.1 documentation</title> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=80d5e7a1" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=86f27845" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" /> <link rel="stylesheet" type="text/css" href="_static/css/custom.css?v=0731ccc3" /> <link rel="shortcut icon" href="_static/favicon.ico"/> <script src="_static/jquery.js?v=8dae8fb0"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=888ff710"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> <script src="_static/jquery.js?v=5d32c60e"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=9bcbadda"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> <script src="_static/js/theme.js"></script> <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" />
-
@@ -122,9 +123,9 @@ so the left-hand side of <code class="docutils literal notranslate"><span class="pre">mul_assoc</span></code> could also be written <code class="docutils literal notranslate"><span class="pre">(a</span> <span class="pre">*</span> <span class="pre">b)</span> <span class="pre">*</span> <span class="pre">c</span></code>.However, it is generally good style to be mindful of Lean’s notational conventions and leave out parentheses when Lean does as well.</p> <p>Let’s try out <code class="docutils literal notranslate"><span class="pre">rw</span></code>.</p> <div class="highlight-lean notranslate" id="index-1"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">c</span> <span class="bp">=</span> <span class="n">b</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">c</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mul_comm</span> <span class="n">a</span> <span class="n">b</span><span class="o">]</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mul_assoc</span> <span class="n">b</span> <span class="n">a</span> <span class="n">c</span><span class="o">]</span> <div class="highlight-lean notranslate" id="index-1"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mul_comm</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="o">]</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mul_assoc</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">c</span><span class="o">]</span> </pre></div> </div> <p>The <code class="docutils literal notranslate"><span class="pre">import</span></code> lines at the beginning of the associated examples file
-
@@ -148,12 +149,12 @@ <em>Lean Infoview</em> window.As you move your cursor past each step of the proof, you can see the state change. A typical proof state in Lean might look as follows:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="n">goal</span> <span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">,</span> <span class="n">h₁</span> <span class="o">:</span> <span class="n">Prime</span> <span class="n">x</span><span class="o">,</span> <span class="n">h₂</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">Even</span> <span class="n">x</span><span class="o">,</span> <span class="n">h₃</span> <span class="o">:</span> <span class="n">y</span> <span class="bp">></span> <span class="n">x</span> <span class="bp">⊢</span> <span class="n">y</span> <span class="bp">≥</span> <span class="mi">4</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span><span class="w"> </span><span class="n">goal</span> <span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">,</span> <span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Prime</span><span class="w"> </span><span class="n">x</span><span class="o">,</span> <span class="n">h₂</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">Even</span><span class="w"> </span><span class="n">x</span><span class="o">,</span> <span class="n">h₃</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">x</span> <span class="bp">⊢</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="mi">4</span> </pre></div> </div> <p>The lines before the one that begins with <code class="docutils literal notranslate"><span class="pre">⊢</span></code> denote the <em>context</em>:
-
@@ -180,20 +181,20 @@ For example, <code class="docutils literal notranslate"><span class="pre">rw</span> <span class="pre">[←</span> <span class="pre">mul_assoc</span> <span class="pre">a</span> <span class="pre">b</span> <span class="pre">c]</span></code>replaces <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">*</span> <span class="pre">(b</span> <span class="pre">*</span> <span class="pre">c)</span></code> by <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">*</span> <span class="pre">b</span> <span class="pre">*</span> <span class="pre">c</span></code> in the current goal. Note that the left-pointing arrow refers to going from right to left in the identity provided by <code class="docutils literal notranslate"><span class="pre">mul_assoc</span></code>, it has nothing to do with the left or right side of the goal.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">c</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">=</span> <span class="n">b</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">c</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="o">(</span><span class="n">b</span> <span class="bp">*</span> <span class="n">c</span><span class="o">)</span> <span class="bp">=</span> <span class="n">b</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">c</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>You can also use identities like <code class="docutils literal notranslate"><span class="pre">mul_assoc</span></code> and <code class="docutils literal notranslate"><span class="pre">mul_comm</span></code> without arguments. In this case, the rewrite tactic tries to match the left-hand side with an expression in the goal, using the first pattern it finds.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">c</span> <span class="bp">=</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">c</span> <span class="bp">*</span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mul_assoc</span><span class="o">]</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mul_comm</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mul_assoc</span><span class="o">]</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mul_comm</span><span class="o">]</span> </pre></div> </div> <p>You can also provide <em>partial</em> information.
-
@@ -202,43 +203,43 @@ <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">*</span> <span class="pre">?</span></code> and rewrites it to <code class="docutils literal notranslate"><span class="pre">?</span> <span class="pre">*</span> <span class="pre">a</span></code>.Try doing the first of these examples without providing any arguments at all, and the second with only one argument.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="o">(</span><span class="n">b</span> <span class="bp">*</span> <span class="n">c</span><span class="o">)</span> <span class="bp">=</span> <span class="n">b</span> <span class="bp">*</span> <span class="o">(</span><span class="n">c</span> <span class="bp">*</span> <span class="n">a</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="o">(</span><span class="n">b</span> <span class="bp">*</span> <span class="n">c</span><span class="o">)</span> <span class="bp">=</span> <span class="n">b</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">c</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>You can also use <code class="docutils literal notranslate"><span class="pre">rw</span></code> with facts from the local context.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="n">d</span> <span class="n">e</span> <span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">c</span> <span class="bp">*</span> <span class="n">d</span><span class="o">)</span> <span class="o">(</span><span class="n">h'</span> <span class="o">:</span> <span class="n">e</span> <span class="bp">=</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="o">(</span><span class="n">b</span> <span class="bp">*</span> <span class="n">e</span><span class="o">)</span> <span class="bp">=</span> <span class="n">c</span> <span class="bp">*</span> <span class="o">(</span><span class="n">d</span> <span class="bp">*</span> <span class="n">f</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">h'</span><span class="o">]</span> <span class="n">rw</span> <span class="o">[</span><span class="bp">←</span> <span class="n">mul_assoc</span><span class="o">]</span> <span class="n">rw</span> <span class="o">[</span><span class="n">h</span><span class="o">]</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mul_assoc</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">d</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">e</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">d</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">h'</span><span class="o">]</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="bp">←</span><span class="w"> </span><span class="n">mul_assoc</span><span class="o">]</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">h</span><span class="o">]</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mul_assoc</span><span class="o">]</span> </pre></div> </div> <p>Try these, using the theorem <code class="docutils literal notranslate"><span class="pre">sub_self</span></code> for the second one:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="n">d</span> <span class="n">e</span> <span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">c</span> <span class="bp">=</span> <span class="n">e</span> <span class="bp">*</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">c</span> <span class="bp">*</span> <span class="n">d</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">e</span> <span class="bp">*</span> <span class="n">f</span> <span class="bp">*</span> <span class="n">d</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="n">d</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">hyp</span> <span class="o">:</span> <span class="n">c</span> <span class="bp">=</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">-</span> <span class="n">d</span><span class="o">)</span> <span class="o">(</span><span class="n">hyp'</span> <span class="o">:</span> <span class="n">d</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span><span class="o">)</span> <span class="o">:</span> <span class="n">c</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hyp</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">d</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hyp'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Multiple rewrite commands can be carried out with a single command, by listing the relevant identities separated by commas inside the square brackets.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="n">d</span> <span class="n">e</span> <span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">c</span> <span class="bp">*</span> <span class="n">d</span><span class="o">)</span> <span class="o">(</span><span class="n">h'</span> <span class="o">:</span> <span class="n">e</span> <span class="bp">=</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="o">(</span><span class="n">b</span> <span class="bp">*</span> <span class="n">e</span><span class="o">)</span> <span class="bp">=</span> <span class="n">c</span> <span class="bp">*</span> <span class="o">(</span><span class="n">d</span> <span class="bp">*</span> <span class="n">f</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">h'</span><span class="o">,</span> <span class="bp">←</span> <span class="n">mul_assoc</span><span class="o">,</span> <span class="n">h</span><span class="o">,</span> <span class="n">mul_assoc</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">d</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">e</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">d</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">h'</span><span class="o">,</span><span class="w"> </span><span class="bp">←</span><span class="w"> </span><span class="n">mul_assoc</span><span class="o">,</span><span class="w"> </span><span class="n">h</span><span class="o">,</span><span class="w"> </span><span class="n">mul_assoc</span><span class="o">]</span> </pre></div> </div> <p>You still see the incremental progress by placing the cursor after a comma in any list of rewrites.</p> <p>Another trick is that we can declare variables once and for all outside an example or theorem. Lean then includes them automatically.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="n">d</span> <span class="n">e</span> <span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">c</span> <span class="bp">*</span> <span class="n">d</span><span class="o">)</span> <span class="o">(</span><span class="n">h'</span> <span class="o">:</span> <span class="n">e</span> <span class="bp">=</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="o">(</span><span class="n">b</span> <span class="bp">*</span> <span class="n">e</span><span class="o">)</span> <span class="bp">=</span> <span class="n">c</span> <span class="bp">*</span> <span class="o">(</span><span class="n">d</span> <span class="bp">*</span> <span class="n">f</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">h'</span><span class="o">,</span> <span class="bp">←</span> <span class="n">mul_assoc</span><span class="o">,</span> <span class="n">h</span><span class="o">,</span> <span class="n">mul_assoc</span><span class="o">]</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">d</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">e</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">d</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">h'</span><span class="o">,</span><span class="w"> </span><span class="bp">←</span><span class="w"> </span><span class="n">mul_assoc</span><span class="o">,</span><span class="w"> </span><span class="n">h</span><span class="o">,</span><span class="w"> </span><span class="n">mul_assoc</span><span class="o">]</span> </pre></div> </div> <p>Inspection of the tactic state at the beginning of the above proof
-
@@ -248,16 +249,16 @@ in a <code class="docutils literal notranslate"><span class="pre">section</span> <span class="pre">...</span> <span class="pre">end</span></code> block.Finally, recall from the introduction that Lean provides us with a command to determine the type of an expression:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span> <span class="k">#check</span> <span class="n">a</span> <span class="k">#check</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">b</span> <span class="k">#check</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="k">#check</span> <span class="n">mul_comm</span> <span class="n">a</span> <span class="n">b</span> <span class="k">#check</span> <span class="o">(</span><span class="n">mul_comm</span> <span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">a</span><span class="o">)</span> <span class="k">#check</span> <span class="n">mul_assoc</span> <span class="n">c</span> <span class="n">a</span> <span class="n">b</span> <span class="k">#check</span> <span class="n">mul_comm</span> <span class="n">a</span> <span class="k">#check</span> <span class="n">mul_comm</span> <span class="k">#check</span><span class="w"> </span><span class="n">a</span> <span class="k">#check</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="n">mul_comm</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">mul_comm</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="n">mul_assoc</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span> <span class="k">#check</span><span class="w"> </span><span class="n">mul_comm</span><span class="w"> </span><span class="n">a</span> <span class="k">#check</span><span class="w"> </span><span class="n">mul_comm</span> <span class="kd">end</span> </pre></div>
-
@@ -277,10 +278,10 @@ that <code class="docutils literal notranslate"><span class="pre">2</span> <span class="pre">*</span> <span class="pre">a</span> <span class="pre">=</span> <span class="pre">a</span> <span class="pre">+</span> <span class="pre">a</span></code>. The theorems <code class="docutils literal notranslate"><span class="pre">add_mul</span></code> and <code class="docutils literal notranslate"><span class="pre">mul_add</span></code>express the distributivity of multiplication over addition, and the theorem <code class="docutils literal notranslate"><span class="pre">add_assoc</span></code> expresses the associativity of addition. Use the <code class="docutils literal notranslate"><span class="pre">#check</span></code> command to see the precise statements.</p> <div class="highlight-lean notranslate" id="index-3"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">+</span> <span class="mi">2</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">b</span><span class="o">)</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">b</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mul_add</span><span class="o">,</span> <span class="n">add_mul</span><span class="o">,</span> <span class="n">add_mul</span><span class="o">]</span> <span class="n">rw</span> <span class="o">[</span><span class="bp">←</span> <span class="n">add_assoc</span><span class="o">,</span> <span class="n">add_assoc</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">a</span><span class="o">)]</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mul_comm</span> <span class="n">b</span> <span class="n">a</span><span class="o">,</span> <span class="bp">←</span> <span class="n">two_mul</span><span class="o">]</span> <div class="highlight-lean notranslate" id="index-3"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mul_add</span><span class="o">,</span><span class="w"> </span><span class="n">add_mul</span><span class="o">,</span><span class="w"> </span><span class="n">add_mul</span><span class="o">]</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="bp">←</span><span class="w"> </span><span class="n">add_assoc</span><span class="o">,</span><span class="w"> </span><span class="n">add_assoc</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="o">)]</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mul_comm</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="bp">←</span><span class="w"> </span><span class="n">two_mul</span><span class="o">]</span> </pre></div> </div> <p>Whereas it is possible to figure out what it going on in this proof
-
@@ -288,14 +289,14 @@ by stepping through it in the editor,it is hard to read on its own. Lean provides a more structured way of writing proofs like this using the <code class="docutils literal notranslate"><span class="pre">calc</span></code> keyword.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">+</span> <span class="mi">2</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">b</span><span class="o">)</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">b</span> <span class="o">:=</span> <span class="k">calc</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">+</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">b</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mul_add</span><span class="o">,</span> <span class="n">add_mul</span><span class="o">,</span> <span class="n">add_mul</span><span class="o">]</span> <span class="n">_</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">+</span> <span class="o">(</span><span class="n">b</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span><span class="o">)</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">b</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="bp">←</span> <span class="n">add_assoc</span><span class="o">,</span> <span class="n">add_assoc</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">a</span><span class="o">)]</span> <span class="n">_</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">+</span> <span class="mi">2</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">b</span><span class="o">)</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">b</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mul_comm</span> <span class="n">b</span> <span class="n">a</span><span class="o">,</span> <span class="bp">←</span> <span class="n">two_mul</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="k">calc</span> <span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mul_add</span><span class="o">,</span><span class="w"> </span><span class="n">add_mul</span><span class="o">,</span><span class="w"> </span><span class="n">add_mul</span><span class="o">]</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="bp">←</span><span class="w"> </span><span class="n">add_assoc</span><span class="o">,</span><span class="w"> </span><span class="n">add_assoc</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="o">)]</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mul_comm</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="bp">←</span><span class="w"> </span><span class="n">two_mul</span><span class="o">]</span> </pre></div> </div> <p>Notice that the proof does <em>not</em> begin with <code class="docutils literal notranslate"><span class="pre">by</span></code>:
-
@@ -312,44 +313,44 @@ <p>One way to write a <code class="docutils literal notranslate"><span class="pre">calc</span></code> proof is to outline it firstusing the <code class="docutils literal notranslate"><span class="pre">sorry</span></code> tactic for justification, make sure Lean accepts the expression modulo these, and then justify the individual steps using tactics.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">+</span> <span class="mi">2</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">b</span><span class="o">)</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">b</span> <span class="o">:=</span> <span class="k">calc</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">+</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">b</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="n">_</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">+</span> <span class="o">(</span><span class="n">b</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span><span class="o">)</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">b</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="n">_</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">+</span> <span class="mi">2</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">b</span><span class="o">)</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">b</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="k">calc</span> <span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Try proving the following identity using both a pure <code class="docutils literal notranslate"><span class="pre">rw</span></code> proof and a more structured <code class="docutils literal notranslate"><span class="pre">calc</span></code> proof:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">*</span> <span class="o">(</span><span class="n">c</span> <span class="bp">+</span> <span class="n">d</span><span class="o">)</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">c</span> <span class="bp">+</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">d</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">c</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">d</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">c</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">d</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>The following exercise is a little more challenging. You can use the theorems listed underneath.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">-</span> <span class="n">b</span><span class="o">)</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">-</span> <span class="n">b</span> <span class="bp">^</span> <span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="k">#check</span> <span class="n">pow_two</span> <span class="n">a</span> <span class="k">#check</span> <span class="n">mul_sub</span> <span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="k">#check</span> <span class="n">add_mul</span> <span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="k">#check</span> <span class="n">add_sub</span> <span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="k">#check</span> <span class="n">sub_sub</span> <span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="k">#check</span> <span class="n">add_zero</span> <span class="n">a</span> <span class="k">#check</span><span class="w"> </span><span class="n">pow_two</span><span class="w"> </span><span class="n">a</span> <span class="k">#check</span><span class="w"> </span><span class="n">mul_sub</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span> <span class="k">#check</span><span class="w"> </span><span class="n">add_mul</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span> <span class="k">#check</span><span class="w"> </span><span class="n">add_sub</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span> <span class="k">#check</span><span class="w"> </span><span class="n">sub_sub</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span> <span class="k">#check</span><span class="w"> </span><span class="n">add_zero</span><span class="w"> </span><span class="n">a</span> </pre></div> </div> <p id="index-4">We can also perform rewriting in an assumption in the context. For example, <code class="docutils literal notranslate"><span class="pre">rw</span> <span class="pre">[mul_comm</span> <span class="pre">a</span> <span class="pre">b]</span> <span class="pre">at</span> <span class="pre">hyp</span></code> replaces <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">*</span> <span class="pre">b</span></code> by <code class="docutils literal notranslate"><span class="pre">b</span> <span class="pre">*</span> <span class="pre">a</span></code> in the assumption <code class="docutils literal notranslate"><span class="pre">hyp</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="n">d</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">hyp</span> <span class="o">:</span> <span class="n">c</span> <span class="bp">=</span> <span class="n">d</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="o">(</span><span class="n">hyp'</span> <span class="o">:</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">d</span><span class="o">)</span> <span class="o">:</span> <span class="n">c</span> <span class="bp">=</span> <span class="mi">2</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">d</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">hyp'</span><span class="o">]</span> <span class="n">at</span> <span class="n">hyp</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mul_comm</span> <span class="n">d</span> <span class="n">a</span><span class="o">]</span> <span class="n">at</span> <span class="n">hyp</span> <span class="n">rw</span> <span class="o">[</span><span class="bp">←</span> <span class="n">two_mul</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">d</span><span class="o">)]</span> <span class="n">at</span> <span class="n">hyp</span> <span class="n">rw</span> <span class="o">[</span><span class="bp">←</span> <span class="n">mul_assoc</span> <span class="mi">2</span> <span class="n">a</span> <span class="n">d</span><span class="o">]</span> <span class="n">at</span> <span class="n">hyp</span> <span class="n">exact</span> <span class="n">hyp</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hyp</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hyp'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">d</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">hyp'</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">hyp</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mul_comm</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="n">a</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">hyp</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="bp">←</span><span class="w"> </span><span class="n">two_mul</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">d</span><span class="o">)]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">hyp</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="bp">←</span><span class="w"> </span><span class="n">mul_assoc</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">d</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">hyp</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">hyp</span> </pre></div> </div> <p id="index-5">In the last step, the <code class="docutils literal notranslate"><span class="pre">exact</span></code> tactic can use <code class="docutils literal notranslate"><span class="pre">hyp</span></code> to solve the goal
-
@@ -358,18 +359,18 @@ <p id="index-6">We close this section by noting that Mathlib provides auseful bit of automation with a <code class="docutils literal notranslate"><span class="pre">ring</span></code> tactic, which is designed to prove identities in any commutative ring as long as they follow purely from the ring axioms, without using any local assumption.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">c</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">=</span> <span class="n">b</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">c</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ring</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">ring</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">+</span> <span class="mi">2</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">b</span><span class="o">)</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">b</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ring</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">ring</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">-</span> <span class="n">b</span><span class="o">)</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">-</span> <span class="n">b</span> <span class="bp">^</span> <span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ring</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">ring</span> <span class="kd">example</span> <span class="o">(</span><span class="n">hyp</span> <span class="o">:</span> <span class="n">c</span> <span class="bp">=</span> <span class="n">d</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="o">(</span><span class="n">hyp'</span> <span class="o">:</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">d</span><span class="o">)</span> <span class="o">:</span> <span class="n">c</span> <span class="bp">=</span> <span class="mi">2</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">d</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">hyp</span><span class="o">,</span> <span class="n">hyp'</span><span class="o">]</span> <span class="n">ring</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">hyp</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hyp'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">d</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">hyp</span><span class="o">,</span><span class="w"> </span><span class="n">hyp'</span><span class="o">]</span> <span class="w"> </span><span class="n">ring</span> </pre></div> </div> <p>The <code class="docutils literal notranslate"><span class="pre">ring</span></code> tactic is imported indirectly when we
-
@@ -384,9 +385,9 @@ <p>There is a variation of <code class="docutils literal notranslate"><span class="pre">rw</span></code> called <code class="docutils literal notranslate"><span class="pre">nth_rw</span></code> that allows you to replace only particular instances of an expression in the goal.Possible matches are enumerated starting with 1, so in the following example, <code class="docutils literal notranslate"><span class="pre">nth_rw</span> <span class="pre">2</span> <span class="pre">[h]</span></code> replaces the second occurrence of <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">+</span> <span class="pre">b</span></code> with <code class="docutils literal notranslate"><span class="pre">c</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">c</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">c</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">c</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">nth_rw</span> <span class="mi">2</span> <span class="o">[</span><span class="n">h</span><span class="o">]</span> <span class="n">rw</span> <span class="o">[</span><span class="n">add_mul</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">nth_rw</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">[</span><span class="n">h</span><span class="o">]</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">add_mul</span><span class="o">]</span> </pre></div> </div> </section>
-
@@ -403,17 +404,17 @@ and multiplication distributes over addition.</p></li></ul> <p>In Lean, the collection of objects is represented as a <em>type</em>, <code class="docutils literal notranslate"><span class="pre">R</span></code>. The ring axioms are as follows:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">(</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">)</span> <span class="o">[</span><span class="n">Ring</span> <span class="n">R</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">Ring</span><span class="w"> </span><span class="n">R</span><span class="o">]</span> <span class="k">#check</span> <span class="o">(</span><span class="n">add_assoc</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">R</span><span class="o">,</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">+</span> <span class="n">c</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">+</span> <span class="o">(</span><span class="n">b</span> <span class="bp">+</span> <span class="n">c</span><span class="o">))</span> <span class="k">#check</span> <span class="o">(</span><span class="n">add_comm</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">R</span><span class="o">,</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">b</span> <span class="bp">+</span> <span class="n">a</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">zero_add</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="o">:</span> <span class="n">R</span><span class="o">,</span> <span class="mi">0</span> <span class="bp">+</span> <span class="n">a</span> <span class="bp">=</span> <span class="n">a</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">neg_add_cancel</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="o">:</span> <span class="n">R</span><span class="o">,</span> <span class="bp">-</span><span class="n">a</span> <span class="bp">+</span> <span class="n">a</span> <span class="bp">=</span> <span class="mi">0</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">mul_assoc</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">R</span><span class="o">,</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">c</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="o">(</span><span class="n">b</span> <span class="bp">*</span> <span class="n">c</span><span class="o">))</span> <span class="k">#check</span> <span class="o">(</span><span class="n">mul_one</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="o">:</span> <span class="n">R</span><span class="o">,</span> <span class="n">a</span> <span class="bp">*</span> <span class="mi">1</span> <span class="bp">=</span> <span class="n">a</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">one_mul</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="o">:</span> <span class="n">R</span><span class="o">,</span> <span class="mi">1</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">=</span> <span class="n">a</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">mul_add</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">R</span><span class="o">,</span> <span class="n">a</span> <span class="bp">*</span> <span class="o">(</span><span class="n">b</span> <span class="bp">+</span> <span class="n">c</span><span class="o">)</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">+</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">c</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">add_mul</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">R</span><span class="o">,</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">*</span> <span class="n">c</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">c</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">c</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">add_assoc</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="o">))</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">add_comm</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">a</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">zero_add</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">,</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">neg_add_cancel</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">,</span><span class="w"> </span><span class="bp">-</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">mul_assoc</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="o">))</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">mul_one</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">one_mul</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">mul_add</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">add_mul</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">,</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="o">)</span> </pre></div> </div> <p>You will learn more about the square brackets in the first line later,
-
@@ -450,18 +451,18 @@ form a ring in which commutativity usually fails. If we declare <code class="docutils literal notranslate"><span class="pre">R</span></code> to be a<em>commutative</em> ring, in fact, all the theorems in the last section continue to hold when we replace <code class="docutils literal notranslate"><span class="pre">ℝ</span></code> by <code class="docutils literal notranslate"><span class="pre">R</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">(</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">)</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="n">d</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">c</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">=</span> <span class="n">b</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">c</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ring</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">ring</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">+</span> <span class="mi">2</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">b</span><span class="o">)</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">b</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ring</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">ring</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">-</span> <span class="n">b</span><span class="o">)</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">-</span> <span class="n">b</span> <span class="bp">^</span> <span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ring</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">ring</span> <span class="kd">example</span> <span class="o">(</span><span class="n">hyp</span> <span class="o">:</span> <span class="n">c</span> <span class="bp">=</span> <span class="n">d</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="o">(</span><span class="n">hyp'</span> <span class="o">:</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">d</span><span class="o">)</span> <span class="o">:</span> <span class="n">c</span> <span class="bp">=</span> <span class="mi">2</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">d</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">hyp</span><span class="o">,</span> <span class="n">hyp'</span><span class="o">]</span> <span class="n">ring</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">hyp</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hyp'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">d</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">hyp</span><span class="o">,</span><span class="w"> </span><span class="n">hyp'</span><span class="o">]</span> <span class="w"> </span><span class="n">ring</span> </pre></div> </div> <p>We leave it to you to check that all the other proofs go through unchanged.
-
@@ -490,17 +491,17 @@ in the next example we put our versions of the librarytheorems in a new namespace called <code class="docutils literal notranslate"><span class="pre">MyRing.</span></code></p> <p>The next example shows that we do not need <code class="docutils literal notranslate"><span class="pre">add_zero</span></code> or <code class="docutils literal notranslate"><span class="pre">add_right_neg</span></code> as ring axioms, because they follow from the other axioms.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">namespace</span> <span class="n">MyRing</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Ring</span> <span class="n">R</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">namespace</span><span class="w"> </span><span class="n">MyRing</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Ring</span><span class="w"> </span><span class="n">R</span><span class="o">]</span> <span class="kd">theorem</span> <span class="n">add_zero</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">+</span> <span class="mi">0</span> <span class="bp">=</span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">add_comm</span><span class="o">,</span> <span class="n">zero_add</span><span class="o">]</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">add_zero</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">add_comm</span><span class="o">,</span><span class="w"> </span><span class="n">zero_add</span><span class="o">]</span> <span class="kd">theorem</span> <span class="n">add_right_neg</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">+</span> <span class="bp">-</span><span class="n">a</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">add_comm</span><span class="o">,</span> <span class="n">neg_add_cancel</span><span class="o">]</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">add_right_neg</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="bp">-</span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">add_comm</span><span class="o">,</span><span class="w"> </span><span class="n">neg_add_cancel</span><span class="o">]</span> <span class="k">#check</span> <span class="n">MyRing.add_zero</span> <span class="k">#check</span> <span class="n">add_zero</span> <span class="k">#check</span><span class="w"> </span><span class="n">MyRing.add_zero</span> <span class="k">#check</span><span class="w"> </span><span class="n">add_zero</span> <span class="kd">end</span> <span class="n">MyRing</span> <span class="kd">end</span><span class="w"> </span><span class="n">MyRing</span> </pre></div> </div> <p>The net effect is that we can temporarily reprove a theorem in the library,
-
@@ -515,21 +516,21 @@ This declares <code class="docutils literal notranslate"><span class="pre">R</span></code> to be an <em>implicit argument</em>.We will explain what this means in a moment, but don’t worry about it in the meanwhile.)</p> <p>Here is a useful theorem:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">neg_add_cancel_left</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="bp">-</span><span class="n">a</span> <span class="bp">+</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">=</span> <span class="n">b</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="bp">←</span> <span class="n">add_assoc</span><span class="o">,</span> <span class="n">neg_add_cancel</span><span class="o">,</span> <span class="n">zero_add</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">neg_add_cancel_left</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">-</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="bp">←</span><span class="w"> </span><span class="n">add_assoc</span><span class="o">,</span><span class="w"> </span><span class="n">neg_add_cancel</span><span class="o">,</span><span class="w"> </span><span class="n">zero_add</span><span class="o">]</span> </pre></div> </div> <p>Prove the companion version:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">add_neg_cancel_right</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">+</span> <span class="bp">-</span><span class="n">b</span> <span class="bp">=</span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">add_neg_cancel_right</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="bp">-</span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Use these to prove the following:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">add_left_cancel</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">R</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">c</span><span class="o">)</span> <span class="o">:</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">c</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">add_left_cancel</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">theorem</span> <span class="n">add_right_cancel</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">R</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">c</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">=</span> <span class="n">c</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">add_right_cancel</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>With enough planning, you can do each of them with three rewrites.</p>
-
@@ -557,10 +558,10 @@ So, given the statement of the theorem above,the correct expression is simply <code class="docutils literal notranslate"><span class="pre">add_left_cancel</span> <span class="pre">h</span></code>.</p> <p>To illustrate, let us show that <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">*</span> <span class="pre">0</span> <span class="pre">=</span> <span class="pre">0</span></code> follows from the ring axioms.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">mul_zero</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="mi">0</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="k">have</span> <span class="n">h</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="mi">0</span> <span class="bp">+</span> <span class="n">a</span> <span class="bp">*</span> <span class="mi">0</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="mi">0</span> <span class="bp">+</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="bp">←</span> <span class="n">mul_add</span><span class="o">,</span> <span class="n">add_zero</span><span class="o">,</span> <span class="n">add_zero</span><span class="o">]</span> <span class="n">rw</span> <span class="o">[</span><span class="n">add_left_cancel</span> <span class="n">h</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">mul_zero</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="bp">←</span><span class="w"> </span><span class="n">mul_add</span><span class="o">,</span><span class="w"> </span><span class="n">add_zero</span><span class="o">,</span><span class="w"> </span><span class="n">add_zero</span><span class="o">]</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">add_left_cancel</span><span class="w"> </span><span class="n">h</span><span class="o">]</span> </pre></div> </div> <p id="index-11">We have used a new trick!
-
@@ -590,26 +591,26 @@ than <code class="docutils literal notranslate"><span class="pre">apply</span></code>, it makes proof scripts slightly clearer tohuman readers and easier to maintain when the library evolves.</p> <p>Remember that multiplication is not assumed to be commutative, so the following theorem also requires some work.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">zero_mul</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">zero_mul</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>By now, you should also be able replace each <code class="docutils literal notranslate"><span class="pre">sorry</span></code> in the next exercise with a proof, still using only facts about rings that we have established in this section.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">neg_eq_of_add_eq_zero</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">R</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">=</span> <span class="mi">0</span><span class="o">)</span> <span class="o">:</span> <span class="bp">-</span><span class="n">a</span> <span class="bp">=</span> <span class="n">b</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">neg_eq_of_add_eq_zero</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">-</span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">theorem</span> <span class="n">eq_neg_of_add_eq_zero</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">R</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">=</span> <span class="mi">0</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">=</span> <span class="bp">-</span><span class="n">b</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">eq_neg_of_add_eq_zero</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">-</span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">theorem</span> <span class="n">neg_zero</span> <span class="o">:</span> <span class="o">(</span><span class="bp">-</span><span class="mi">0</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">neg_eq_of_add_eq_zero</span> <span class="n">rw</span> <span class="o">[</span><span class="n">add_zero</span><span class="o">]</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">neg_zero</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">-</span><span class="mi">0</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">neg_eq_of_add_eq_zero</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">add_zero</span><span class="o">]</span> <span class="kd">theorem</span> <span class="n">neg_neg</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="bp">-</span> <span class="bp">-</span><span class="n">a</span> <span class="bp">=</span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">neg_neg</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="bp">-</span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>We had to use the annotation <code class="docutils literal notranslate"><span class="pre">(-0</span> <span class="pre">:</span> <span class="pre">R)</span></code> instead of <code class="docutils literal notranslate"><span class="pre">0</span></code> in the third theorem
-
@@ -618,16 +619,16 @@ it is impossible for Lean to infer which <code class="docutils literal notranslate"><span class="pre">0</span></code> we have in mind,and by default it would be interpreted as a natural number.</p> <p>In Lean, subtraction in a ring is provably equal to addition of the additive inverse.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">-</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">+</span> <span class="bp">-</span><span class="n">b</span> <span class="o">:=</span> <span class="n">sub_eq_add_neg</span> <span class="n">a</span> <span class="n">b</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="bp">-</span><span class="n">b</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">sub_eq_add_neg</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span> </pre></div> </div> <p>On the real numbers, it is <em>defined</em> that way:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">-</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">+</span> <span class="bp">-</span><span class="n">b</span> <span class="o">:=</span> <span class="n">rfl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="bp">-</span><span class="n">b</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">-</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">+</span> <span class="bp">-</span><span class="n">b</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="bp">-</span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rfl</span> </pre></div> </div> <p id="index-13">The proof term <code class="docutils literal notranslate"><span class="pre">rfl</span></code> is short for “reflexivity”.
-
@@ -642,8 +643,8 @@ but in some contexts, when dealing with the real numbers,you can use the two sides of the equation interchangeably. For example, you now have enough information to prove the theorem <code class="docutils literal notranslate"><span class="pre">self_sub</span></code> from the last section:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">self_sub</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">-</span> <span class="n">a</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">self_sub</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Show that you can prove this using <code class="docutils literal notranslate"><span class="pre">rw</span></code>,
-
@@ -654,11 +655,11 @@ <p>Lean knows that <code class="docutils literal notranslate"><span class="pre">1</span> <span class="pre">+</span> <span class="pre">1</span> <span class="pre">=</span> <span class="pre">2</span></code> holds in any ring.With a bit of effort, you can use that to prove the theorem <code class="docutils literal notranslate"><span class="pre">two_mul</span></code> from the last section:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">one_add_one_eq_two</span> <span class="o">:</span> <span class="mi">1</span> <span class="bp">+</span> <span class="mi">1</span> <span class="bp">=</span> <span class="o">(</span><span class="mi">2</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">norm_num</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">one_add_one_eq_two</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="mi">2</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">norm_num</span> <span class="kd">theorem</span> <span class="n">two_mul</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">two_mul</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p id="index-14">We close this section by noting that some of the facts about
-
@@ -666,11 +667,11 @@ addition and negation that we established above do notneed the full strength of the ring axioms, or even commutativity of addition. The weaker notion of a <em>group</em> can be axiomatized as follows:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">(</span><span class="n">A</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">)</span> <span class="o">[</span><span class="n">AddGroup</span> <span class="n">A</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">A</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">AddGroup</span><span class="w"> </span><span class="n">A</span><span class="o">]</span> <span class="k">#check</span> <span class="o">(</span><span class="n">add_assoc</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">A</span><span class="o">,</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">+</span> <span class="n">c</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">+</span> <span class="o">(</span><span class="n">b</span> <span class="bp">+</span> <span class="n">c</span><span class="o">))</span> <span class="k">#check</span> <span class="o">(</span><span class="n">zero_add</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="o">:</span> <span class="n">A</span><span class="o">,</span> <span class="mi">0</span> <span class="bp">+</span> <span class="n">a</span> <span class="bp">=</span> <span class="n">a</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">neg_add_cancel</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="o">:</span> <span class="n">A</span><span class="o">,</span> <span class="bp">-</span><span class="n">a</span> <span class="bp">+</span> <span class="n">a</span> <span class="bp">=</span> <span class="mi">0</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">add_assoc</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">A</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="o">))</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">zero_add</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">A</span><span class="o">,</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">neg_add_cancel</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">A</span><span class="o">,</span><span class="w"> </span><span class="bp">-</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span> </pre></div> </div> <p>It is conventional to use additive notation when
-
@@ -679,25 +680,25 @@ and multiplicative notation otherwise.So Lean defines a multiplicative version as well as the additive version (and also their abelian variants, <code class="docutils literal notranslate"><span class="pre">AddCommGroup</span></code> and <code class="docutils literal notranslate"><span class="pre">CommGroup</span></code>).</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span> <span class="k">#check</span> <span class="o">(</span><span class="n">mul_assoc</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">G</span><span class="o">,</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">c</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="o">(</span><span class="n">b</span> <span class="bp">*</span> <span class="n">c</span><span class="o">))</span> <span class="k">#check</span> <span class="o">(</span><span class="n">one_mul</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="o">:</span> <span class="n">G</span><span class="o">,</span> <span class="mi">1</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">=</span> <span class="n">a</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">inv_mul_cancel</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="o">:</span> <span class="n">G</span><span class="o">,</span> <span class="n">a</span><span class="bp">⁻¹</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">=</span> <span class="mi">1</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">mul_assoc</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="o">))</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">one_mul</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">inv_mul_cancel</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="bp">⁻¹</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span> </pre></div> </div> <p>If you are feeling cocky, try proving the following facts about groups, using only these axioms. You will need to prove a number of helper lemmas along the way. The proofs we have carried out in this section provide some hints.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">mul_inv_cancel</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">a</span><span class="bp">⁻¹</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">mul_inv_cancel</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="bp">⁻¹</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">theorem</span> <span class="n">mul_one</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="mi">1</span> <span class="bp">=</span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">mul_one</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">theorem</span> <span class="n">mul_inv_rev</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">b</span><span class="o">)</span><span class="bp">⁻¹</span> <span class="bp">=</span> <span class="n">b</span><span class="bp">⁻¹</span> <span class="bp">*</span> <span class="n">a</span><span class="bp">⁻¹</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">mul_inv_rev</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="bp">⁻¹</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="bp">⁻¹</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="bp">⁻¹</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p id="index-15">Explicitly invoking those lemmas is tedious, so Mathlib provides
-
@@ -720,8 +721,8 @@ We have already seen that theorems can be applied to arguments and hypotheses,and that the <code class="docutils literal notranslate"><span class="pre">apply</span></code> and <code class="docutils literal notranslate"><span class="pre">exact</span></code> tactics can be used to solve goals. In this section, we will make good use of these tools.</p> <p>Consider the library theorems <code class="docutils literal notranslate"><span class="pre">le_refl</span></code> and <code class="docutils literal notranslate"><span class="pre">le_trans</span></code>:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="o">(</span><span class="n">le_refl</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">,</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">a</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">le_trans</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">→</span> <span class="n">b</span> <span class="bp">≤</span> <span class="n">c</span> <span class="bp">→</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">c</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">le_refl</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">le_trans</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">c</span><span class="o">)</span> </pre></div> </div> <p>As we explain in more detail in <a class="reference internal" href="C03_Logic.html#implication-and-the-universal-quantifier"><span class="std std-numref">Section 3.1</span></a>,
-
@@ -734,13 +735,13 @@ Rather, it expects to infer them from the context in which they are used.For example, when hypotheses <code class="docutils literal notranslate"><span class="pre">h</span> <span class="pre">:</span> <span class="pre">a</span> <span class="pre">≤</span> <span class="pre">b</span></code> and <code class="docutils literal notranslate"><span class="pre">h'</span> <span class="pre">:</span> <span class="pre">b</span> <span class="pre">≤</span> <span class="pre">c</span></code> are in the context, all the following work:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span><span class="o">)</span> <span class="o">(</span><span class="n">h'</span> <span class="o">:</span> <span class="n">b</span> <span class="bp">≤</span> <span class="n">c</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">c</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">le_refl</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="o">:</span> <span class="n">Real</span><span class="o">,</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">a</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">le_refl</span> <span class="n">a</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">a</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">le_trans</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">→</span> <span class="n">b</span> <span class="bp">≤</span> <span class="n">c</span> <span class="bp">→</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">c</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">le_trans</span> <span class="n">h</span> <span class="o">:</span> <span class="n">b</span> <span class="bp">≤</span> <span class="n">c</span> <span class="bp">→</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">c</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">le_trans</span> <span class="n">h</span> <span class="n">h'</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">c</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">le_refl</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Real</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">le_refl</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">le_trans</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">c</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">le_trans</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">c</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">le_trans</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">c</span><span class="o">)</span> </pre></div> </div> <p id="index-17">The <code class="docutils literal notranslate"><span class="pre">apply</span></code> tactic takes a proof of a general statement or implication,
-
@@ -750,23 +751,23 @@ If the given proof matches the goal exactly(modulo <em>definitional</em> equality), you can use the <code class="docutils literal notranslate"><span class="pre">exact</span></code> tactic instead of <code class="docutils literal notranslate"><span class="pre">apply</span></code>. So, all of these work:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="n">z</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">h₀</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span><span class="o">)</span> <span class="o">(</span><span class="n">h₁</span> <span class="o">:</span> <span class="n">y</span> <span class="bp">≤</span> <span class="n">z</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">z</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">le_trans</span> <span class="bp">·</span> <span class="n">apply</span> <span class="n">h₀</span> <span class="bp">·</span> <span class="n">apply</span> <span class="n">h₁</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">z</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">le_trans</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">h₀</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">h₁</span> <span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="n">z</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">h₀</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span><span class="o">)</span> <span class="o">(</span><span class="n">h₁</span> <span class="o">:</span> <span class="n">y</span> <span class="bp">≤</span> <span class="n">z</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">z</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">le_trans</span> <span class="n">h₀</span> <span class="n">apply</span> <span class="n">h₁</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">z</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">le_trans</span><span class="w"> </span><span class="n">h₀</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">h₁</span> <span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="n">z</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">h₀</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span><span class="o">)</span> <span class="o">(</span><span class="n">h₁</span> <span class="o">:</span> <span class="n">y</span> <span class="bp">≤</span> <span class="n">z</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">z</span> <span class="o">:=</span> <span class="n">le_trans</span> <span class="n">h₀</span> <span class="n">h₁</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">z</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">le_trans</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span> <span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">le_refl</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">le_refl</span> <span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">x</span> <span class="o">:=</span> <span class="n">le_refl</span> <span class="n">x</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">le_refl</span><span class="w"> </span><span class="n">x</span> </pre></div> </div> <p>In the first example, applying <code class="docutils literal notranslate"><span class="pre">le_trans</span></code>
-
@@ -781,26 +782,26 @@ In the third example and in the last example,we avoid going into tactic mode entirely: <code class="docutils literal notranslate"><span class="pre">le_trans</span> <span class="pre">h₀</span> <span class="pre">h₁</span></code> and <code class="docutils literal notranslate"><span class="pre">le_refl</span> <span class="pre">x</span></code> are the proof terms we need.</p> <p>Here are a few more library theorems:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="o">(</span><span class="n">le_refl</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span><span class="o">,</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">a</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">le_trans</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">→</span> <span class="n">b</span> <span class="bp">≤</span> <span class="n">c</span> <span class="bp">→</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">c</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">lt_of_le_of_lt</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">→</span> <span class="n">b</span> <span class="bp"><</span> <span class="n">c</span> <span class="bp">→</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">c</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">lt_of_lt_of_le</span> <span class="o">:</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">b</span> <span class="bp">→</span> <span class="n">b</span> <span class="bp">≤</span> <span class="n">c</span> <span class="bp">→</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">c</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">lt_trans</span> <span class="o">:</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">b</span> <span class="bp">→</span> <span class="n">b</span> <span class="bp"><</span> <span class="n">c</span> <span class="bp">→</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">c</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">le_refl</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">le_trans</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">c</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">lt_of_le_of_lt</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">c</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">lt_of_lt_of_le</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">c</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">lt_trans</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">c</span><span class="o">)</span> </pre></div> </div> <p>Use them together with <code class="docutils literal notranslate"><span class="pre">apply</span></code> and <code class="docutils literal notranslate"><span class="pre">exact</span></code> to prove the following:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h₀</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span><span class="o">)</span> <span class="o">(</span><span class="n">h₁</span> <span class="o">:</span> <span class="n">b</span> <span class="bp"><</span> <span class="n">c</span><span class="o">)</span> <span class="o">(</span><span class="n">h₂</span> <span class="o">:</span> <span class="n">c</span> <span class="bp">≤</span> <span class="n">d</span><span class="o">)</span> <span class="o">(</span><span class="n">h₃</span> <span class="o">:</span> <span class="n">d</span> <span class="bp"><</span> <span class="n">e</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">e</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₂</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">d</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₃</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">e</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p id="index-18">In fact, Lean has a tactic that does this sort of thing automatically:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h₀</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span><span class="o">)</span> <span class="o">(</span><span class="n">h₁</span> <span class="o">:</span> <span class="n">b</span> <span class="bp"><</span> <span class="n">c</span><span class="o">)</span> <span class="o">(</span><span class="n">h₂</span> <span class="o">:</span> <span class="n">c</span> <span class="bp">≤</span> <span class="n">d</span><span class="o">)</span> <span class="o">(</span><span class="n">h₃</span> <span class="o">:</span> <span class="n">d</span> <span class="bp"><</span> <span class="n">e</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">e</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">linarith</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₂</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">d</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₃</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">e</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">linarith</span> </pre></div> </div> <p>The <code class="docutils literal notranslate"><span class="pre">linarith</span></code> tactic is designed to handle <em>linear arithmetic</em>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">≤</span> <span class="mi">3</span> <span class="bp">*</span> <span class="n">b</span><span class="o">)</span> <span class="o">(</span><span class="n">h'</span> <span class="o">:</span> <span class="mi">1</span> <span class="bp">≤</span> <span class="n">a</span><span class="o">)</span> <span class="o">(</span><span class="n">h''</span> <span class="o">:</span> <span class="n">d</span> <span class="bp">=</span> <span class="mi">2</span><span class="o">)</span> <span class="o">:</span> <span class="n">d</span> <span class="bp">+</span> <span class="n">a</span> <span class="bp">≤</span> <span class="mi">5</span> <span class="bp">*</span> <span class="n">b</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">linarith</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h''</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">linarith</span> </pre></div> </div> <p>In addition to equations and inequalities in the context,
-
@@ -814,28 +815,28 @@ applying a fact or theorem <code class="docutils literal notranslate"><span class="pre">h</span></code> to the argument <code class="docutils literal notranslate"><span class="pre">x</span></code>.Parentheses are only needed for compound arguments, as in <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">(x</span> <span class="pre">+</span> <span class="pre">y)</span></code>. Without the parentheses, <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">y</span></code> would be parsed as <code class="docutils literal notranslate"><span class="pre">(f</span> <span class="pre">x)</span> <span class="pre">+</span> <span class="pre">y</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="mi">1</span> <span class="bp">≤</span> <span class="n">a</span><span class="o">)</span> <span class="o">(</span><span class="n">h'</span> <span class="o">:</span> <span class="n">b</span> <span class="bp">≤</span> <span class="n">c</span><span class="o">)</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">+</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">exp</span> <span class="n">b</span> <span class="bp">≤</span> <span class="mi">3</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">exp</span> <span class="n">c</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">linarith</span> <span class="o">[</span><span class="n">exp_le_exp.mpr</span> <span class="n">h'</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">linarith</span><span class="w"> </span><span class="o">[</span><span class="n">exp_le_exp.mpr</span><span class="w"> </span><span class="n">h'</span><span class="o">]</span> </pre></div> </div> <p id="index-19">Here are some more theorems in the library that can be used to establish inequalities on the real numbers.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="o">(</span><span class="n">exp_le_exp</span> <span class="o">:</span> <span class="n">exp</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">exp</span> <span class="n">b</span> <span class="bp">↔</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">exp_lt_exp</span> <span class="o">:</span> <span class="n">exp</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">exp</span> <span class="n">b</span> <span class="bp">↔</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">b</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">log_le_log</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">a</span> <span class="bp">→</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">→</span> <span class="n">log</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">log</span> <span class="n">b</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">log_lt_log</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">a</span> <span class="bp">→</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">b</span> <span class="bp">→</span> <span class="n">log</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">log</span> <span class="n">b</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">add_le_add</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">→</span> <span class="n">c</span> <span class="bp">≤</span> <span class="n">d</span> <span class="bp">→</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">c</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">+</span> <span class="n">d</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">add_le_add_left</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">→</span> <span class="bp">∀</span> <span class="n">c</span><span class="o">,</span> <span class="n">c</span> <span class="bp">+</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">c</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">add_le_add_right</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">→</span> <span class="bp">∀</span> <span class="n">c</span><span class="o">,</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">c</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">+</span> <span class="n">c</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">add_lt_add_of_le_of_lt</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">→</span> <span class="n">c</span> <span class="bp"><</span> <span class="n">d</span> <span class="bp">→</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">c</span> <span class="bp"><</span> <span class="n">b</span> <span class="bp">+</span> <span class="n">d</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">add_lt_add_of_lt_of_le</span> <span class="o">:</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">b</span> <span class="bp">→</span> <span class="n">c</span> <span class="bp">≤</span> <span class="n">d</span> <span class="bp">→</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">c</span> <span class="bp"><</span> <span class="n">b</span> <span class="bp">+</span> <span class="n">d</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">add_lt_add_left</span> <span class="o">:</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">b</span> <span class="bp">→</span> <span class="bp">∀</span> <span class="n">c</span><span class="o">,</span> <span class="n">c</span> <span class="bp">+</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">c</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">add_lt_add_right</span> <span class="o">:</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">b</span> <span class="bp">→</span> <span class="bp">∀</span> <span class="n">c</span><span class="o">,</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">c</span> <span class="bp"><</span> <span class="n">b</span> <span class="bp">+</span> <span class="n">c</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">add_nonneg</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">a</span> <span class="bp">→</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">→</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">add_pos</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">a</span> <span class="bp">→</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">b</span> <span class="bp">→</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">add_pos_of_pos_of_nonneg</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">a</span> <span class="bp">→</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">→</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">exp_pos</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span><span class="o">,</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">exp</span> <span class="n">a</span><span class="o">)</span> <span class="k">#check</span> <span class="n">add_le_add_left</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">exp_le_exp</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">exp_lt_exp</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">log_le_log</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">log</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">log</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">log_lt_log</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">log</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">log</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">add_le_add</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">d</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">add_le_add_left</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">c</span><span class="o">,</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">add_le_add_right</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">c</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">add_lt_add_of_le_of_lt</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">d</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">add_lt_add_of_lt_of_le</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">d</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">add_lt_add_left</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">c</span><span class="o">,</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">add_lt_add_right</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">c</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">add_nonneg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">add_pos</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">add_pos_of_pos_of_nonneg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">exp_pos</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="n">a</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="n">add_le_add_left</span> </pre></div> </div> <p>Some of the theorems, <code class="docutils literal notranslate"><span class="pre">exp_le_exp</span></code>, <code class="docutils literal notranslate"><span class="pre">exp_lt_exp</span></code>
-
@@ -845,9 +846,9 @@ (You can type it in VS Code with <code class="docutils literal notranslate"><span class="pre">\lr</span></code> or <code class="docutils literal notranslate"><span class="pre">\iff</span></code>).We will discuss this connective in greater detail in the next chapter. Such a theorem can be used with <code class="docutils literal notranslate"><span class="pre">rw</span></code> to rewrite a goal to an equivalent one:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span><span class="o">)</span> <span class="o">:</span> <span class="n">exp</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">exp</span> <span class="n">b</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">exp_le_exp</span><span class="o">]</span> <span class="n">exact</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">exp_le_exp</span><span class="o">]</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>In this section, however, we will use the fact that if <code class="docutils literal notranslate"><span class="pre">h</span> <span class="pre">:</span> <span class="pre">A</span> <span class="pre">↔</span> <span class="pre">B</span></code>
-
@@ -859,11 +860,11 @@ <code class="docutils literal notranslate"><span class="pre">mpr</span></code> stands for “modus ponens reverse.”You can also use <code class="docutils literal notranslate"><span class="pre">h.1</span></code> and <code class="docutils literal notranslate"><span class="pre">h.2</span></code> for <code class="docutils literal notranslate"><span class="pre">h.mp</span></code> and <code class="docutils literal notranslate"><span class="pre">h.mpr</span></code>, respectively, if you prefer. Thus the following proof works:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h₀</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span><span class="o">)</span> <span class="o">(</span><span class="n">h₁</span> <span class="o">:</span> <span class="n">c</span> <span class="bp"><</span> <span class="n">d</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">exp</span> <span class="n">c</span> <span class="bp">+</span> <span class="n">e</span> <span class="bp"><</span> <span class="n">b</span> <span class="bp">+</span> <span class="n">exp</span> <span class="n">d</span> <span class="bp">+</span> <span class="n">e</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">add_lt_add_of_lt_of_le</span> <span class="bp">·</span> <span class="n">apply</span> <span class="n">add_lt_add_of_le_of_lt</span> <span class="n">h₀</span> <span class="n">apply</span> <span class="n">exp_lt_exp.mpr</span> <span class="n">h₁</span> <span class="n">apply</span> <span class="n">le_refl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">d</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">add_lt_add_of_lt_of_le</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">add_lt_add_of_le_of_lt</span><span class="w"> </span><span class="n">h₀</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">exp_lt_exp.mpr</span><span class="w"> </span><span class="n">h₁</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">le_refl</span> </pre></div> </div> <p>The first line, <code class="docutils literal notranslate"><span class="pre">apply</span> <span class="pre">add_lt_add_of_lt_of_le</span></code>,
-
@@ -873,14 +874,14 @@ proof of the first from the proof of the second.</p><p id="index-20">Try the following examples on your own. The example in the middle shows you that the <code class="docutils literal notranslate"><span class="pre">norm_num</span></code> tactic can be used to solve concrete numeric goals.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h₀</span> <span class="o">:</span> <span class="n">d</span> <span class="bp">≤</span> <span class="n">e</span><span class="o">)</span> <span class="o">:</span> <span class="n">c</span> <span class="bp">+</span> <span class="n">exp</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">d</span><span class="o">)</span> <span class="bp">≤</span> <span class="n">c</span> <span class="bp">+</span> <span class="n">exp</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">e</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">e</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">d</span><span class="o">)</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">e</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="mi">0</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="bp"><</span> <span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">norm_num</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="mi">0</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span><span class="o">)</span> <span class="o">:</span> <span class="n">log</span> <span class="o">(</span><span class="mi">1</span> <span class="bp">+</span> <span class="n">exp</span> <span class="n">a</span><span class="o">)</span> <span class="bp">≤</span> <span class="n">log</span> <span class="o">(</span><span class="mi">1</span> <span class="bp">+</span> <span class="n">exp</span> <span class="n">b</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="k">have</span> <span class="n">h₀</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="mi">1</span> <span class="bp">+</span> <span class="n">exp</span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="n">apply</span> <span class="n">log_le_log</span> <span class="n">h₀</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">log</span><span class="w"> </span><span class="o">(</span><span class="mi">1</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">log</span><span class="w"> </span><span class="o">(</span><span class="mi">1</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">log_le_log</span><span class="w"> </span><span class="n">h₀</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>From these examples, it should be clear that being able to
-
@@ -910,9 +911,9 @@ and you can find similar theorems nearby.</p></li><li><p>You can use the <code class="docutils literal notranslate"><span class="pre">apply?</span></code> tactic, which tries to find the relevant theorem in the library.</p></li> </ul> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">a</span> <span class="bp">^</span> <span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="c1">-- apply?</span> <span class="n">exact</span> <span class="n">sq_nonneg</span> <span class="n">a</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="c1">-- apply?</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">sq_nonneg</span><span class="w"> </span><span class="n">a</span> </pre></div> </div> <p>To try out <code class="docutils literal notranslate"><span class="pre">apply?</span></code> in this example,
-
@@ -920,23 +921,23 @@ delete the <code class="docutils literal notranslate"><span class="pre">exact</span></code> command and uncomment the previous line.Using these tricks, see if you can find what you need to do the next example:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span><span class="o">)</span> <span class="o">:</span> <span class="n">c</span> <span class="bp">-</span> <span class="n">exp</span> <span class="n">b</span> <span class="bp">≤</span> <span class="n">c</span> <span class="bp">-</span> <span class="n">exp</span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Using the same tricks, confirm that <code class="docutils literal notranslate"><span class="pre">linarith</span></code> instead of <code class="docutils literal notranslate"><span class="pre">apply?</span></code> can also finish the job.</p> <p>Here is another example of an inequality:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="mi">2</span><span class="bp">*</span><span class="n">a</span><span class="bp">*</span><span class="n">b</span> <span class="bp">≤</span> <span class="n">a</span><span class="bp">^</span><span class="mi">2</span> <span class="bp">+</span> <span class="n">b</span><span class="bp">^</span><span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="k">have</span> <span class="n">h</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">a</span><span class="bp">^</span><span class="mi">2</span> <span class="bp">-</span> <span class="mi">2</span><span class="bp">*</span><span class="n">a</span><span class="bp">*</span><span class="n">b</span> <span class="bp">+</span> <span class="n">b</span><span class="bp">^</span><span class="mi">2</span> <span class="k">calc</span> <span class="n">a</span><span class="bp">^</span><span class="mi">2</span> <span class="bp">-</span> <span class="mi">2</span><span class="bp">*</span><span class="n">a</span><span class="bp">*</span><span class="n">b</span> <span class="bp">+</span> <span class="n">b</span><span class="bp">^</span><span class="mi">2</span> <span class="bp">=</span> <span class="o">(</span><span class="n">a</span> <span class="bp">-</span> <span class="n">b</span><span class="o">)</span><span class="bp">^</span><span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ring</span> <span class="n">_</span> <span class="bp">≥</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">pow_two_nonneg</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="bp">*</span><span class="n">a</span><span class="bp">*</span><span class="n">b</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span><span class="bp">^</span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="bp">^</span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span><span class="bp">^</span><span class="mi">2</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="mi">2</span><span class="bp">*</span><span class="n">a</span><span class="bp">*</span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="bp">^</span><span class="mi">2</span> <span class="w"> </span><span class="k">calc</span> <span class="w"> </span><span class="n">a</span><span class="bp">^</span><span class="mi">2</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="mi">2</span><span class="bp">*</span><span class="n">a</span><span class="bp">*</span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="bp">^</span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="bp">^</span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">ring</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">pow_two_nonneg</span> <span class="k">calc</span> <span class="mi">2</span><span class="bp">*</span><span class="n">a</span><span class="bp">*</span><span class="n">b</span> <span class="bp">=</span> <span class="mi">2</span><span class="bp">*</span><span class="n">a</span><span class="bp">*</span><span class="n">b</span> <span class="bp">+</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ring</span> <span class="n">_</span> <span class="bp">≤</span> <span class="mi">2</span><span class="bp">*</span><span class="n">a</span><span class="bp">*</span><span class="n">b</span> <span class="bp">+</span> <span class="o">(</span><span class="n">a</span><span class="bp">^</span><span class="mi">2</span> <span class="bp">-</span> <span class="mi">2</span><span class="bp">*</span><span class="n">a</span><span class="bp">*</span><span class="n">b</span> <span class="bp">+</span> <span class="n">b</span><span class="bp">^</span><span class="mi">2</span><span class="o">)</span> <span class="o">:=</span> <span class="n">add_le_add</span> <span class="o">(</span><span class="n">le_refl</span> <span class="n">_</span><span class="o">)</span> <span class="n">h</span> <span class="n">_</span> <span class="bp">=</span> <span class="n">a</span><span class="bp">^</span><span class="mi">2</span> <span class="bp">+</span> <span class="n">b</span><span class="bp">^</span><span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ring</span> <span class="w"> </span><span class="k">calc</span> <span class="w"> </span><span class="mi">2</span><span class="bp">*</span><span class="n">a</span><span class="bp">*</span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">2</span><span class="bp">*</span><span class="n">a</span><span class="bp">*</span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">ring</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">2</span><span class="bp">*</span><span class="n">a</span><span class="bp">*</span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="bp">^</span><span class="mi">2</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="mi">2</span><span class="bp">*</span><span class="n">a</span><span class="bp">*</span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="bp">^</span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">add_le_add</span><span class="w"> </span><span class="o">(</span><span class="n">le_refl</span><span class="w"> </span><span class="n">_</span><span class="o">)</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="bp">^</span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="bp">^</span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">ring</span> </pre></div> </div> <p>Mathlib tends to put spaces around binary operations like <code class="docutils literal notranslate"><span class="pre">*</span></code> and <code class="docutils literal notranslate"><span class="pre">^</span></code>,
-
@@ -956,22 +957,22 @@ <p>In fact, the only cleverness in the proof above is figuringout the hypothesis <code class="docutils literal notranslate"><span class="pre">h</span></code>. Once we have it, the second calculation involves only linear arithmetic, and <code class="docutils literal notranslate"><span class="pre">linarith</span></code> can handle it:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="mi">2</span><span class="bp">*</span><span class="n">a</span><span class="bp">*</span><span class="n">b</span> <span class="bp">≤</span> <span class="n">a</span><span class="bp">^</span><span class="mi">2</span> <span class="bp">+</span> <span class="n">b</span><span class="bp">^</span><span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="k">have</span> <span class="n">h</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">a</span><span class="bp">^</span><span class="mi">2</span> <span class="bp">-</span> <span class="mi">2</span><span class="bp">*</span><span class="n">a</span><span class="bp">*</span><span class="n">b</span> <span class="bp">+</span> <span class="n">b</span><span class="bp">^</span><span class="mi">2</span> <span class="k">calc</span> <span class="n">a</span><span class="bp">^</span><span class="mi">2</span> <span class="bp">-</span> <span class="mi">2</span><span class="bp">*</span><span class="n">a</span><span class="bp">*</span><span class="n">b</span> <span class="bp">+</span> <span class="n">b</span><span class="bp">^</span><span class="mi">2</span> <span class="bp">=</span> <span class="o">(</span><span class="n">a</span> <span class="bp">-</span> <span class="n">b</span><span class="o">)</span><span class="bp">^</span><span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ring</span> <span class="n">_</span> <span class="bp">≥</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">pow_two_nonneg</span> <span class="n">linarith</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="bp">*</span><span class="n">a</span><span class="bp">*</span><span class="n">b</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span><span class="bp">^</span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="bp">^</span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span><span class="bp">^</span><span class="mi">2</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="mi">2</span><span class="bp">*</span><span class="n">a</span><span class="bp">*</span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="bp">^</span><span class="mi">2</span> <span class="w"> </span><span class="k">calc</span> <span class="w"> </span><span class="n">a</span><span class="bp">^</span><span class="mi">2</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="mi">2</span><span class="bp">*</span><span class="n">a</span><span class="bp">*</span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="bp">^</span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="bp">^</span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">ring</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">pow_two_nonneg</span> <span class="w"> </span><span class="n">linarith</span> </pre></div> </div> <p>How nice! We challenge you to use these ideas to prove the following theorem. You can use the theorem <code class="docutils literal notranslate"><span class="pre">abs_le'.mpr</span></code>. You will also need the <code class="docutils literal notranslate"><span class="pre">constructor</span></code> tactic to split a conjunction to two goals; see <a class="reference internal" href="C03_Logic.html#conjunction-and-biimplication"><span class="std std-numref">Section 3.4</span></a>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="bp">|</span><span class="n">a</span><span class="bp">*</span><span class="n">b</span><span class="bp">|</span> <span class="bp">≤</span> <span class="o">(</span><span class="n">a</span><span class="bp">^</span><span class="mi">2</span> <span class="bp">+</span> <span class="n">b</span><span class="bp">^</span><span class="mi">2</span><span class="o">)</span><span class="bp">/</span><span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="bp">*</span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="bp">^</span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="bp">^</span><span class="mi">2</span><span class="o">)</span><span class="bp">/</span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="k">#check</span> <span class="n">abs_le'.mpr</span> <span class="k">#check</span><span class="w"> </span><span class="n">abs_le'.mpr</span> </pre></div> </div> <p>If you managed to solve this, congratulations!
-
@@ -981,9 +982,9 @@ <section id="more-examples-using-apply-and-rw"><span id="more-on-order-and-divisibility"></span><h2><span class="section-number">2.4. </span>More examples using apply and rw<a class="headerlink" href="#more-examples-using-apply-and-rw" title="Link to this heading"></a></h2> <p id="index-21">The <code class="docutils literal notranslate"><span class="pre">min</span></code> function on the real numbers is uniquely characterized by the following three facts:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="o">(</span><span class="n">min_le_left</span> <span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">min</span> <span class="n">a</span> <span class="n">b</span> <span class="bp">≤</span> <span class="n">a</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">min_le_right</span> <span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">min</span> <span class="n">a</span> <span class="n">b</span> <span class="bp">≤</span> <span class="n">b</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">le_min</span> <span class="o">:</span> <span class="n">c</span> <span class="bp">≤</span> <span class="n">a</span> <span class="bp">→</span> <span class="n">c</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">→</span> <span class="n">c</span> <span class="bp">≤</span> <span class="n">min</span> <span class="n">a</span> <span class="n">b</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">min_le_left</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">min_le_right</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">le_min</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> </pre></div> </div> <p>Can you guess the names of the theorems that characterize
-
@@ -1008,16 +1009,16 @@ <p>Using the theorem <code class="docutils literal notranslate"><span class="pre">le_antisymm</span></code>, we can show that tworeal numbers are equal if each is less than or equal to the other. Using this and the facts above, we can show that <code class="docutils literal notranslate"><span class="pre">min</span></code> is commutative:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">min</span> <span class="n">a</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">min</span> <span class="n">b</span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">le_antisymm</span> <span class="bp">·</span> <span class="k">show</span> <span class="n">min</span> <span class="n">a</span> <span class="n">b</span> <span class="bp">≤</span> <span class="n">min</span> <span class="n">b</span> <span class="n">a</span> <span class="n">apply</span> <span class="n">le_min</span> <span class="bp">·</span> <span class="n">apply</span> <span class="n">min_le_right</span> <span class="n">apply</span> <span class="n">min_le_left</span> <span class="bp">·</span> <span class="k">show</span> <span class="n">min</span> <span class="n">b</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">min</span> <span class="n">a</span> <span class="n">b</span> <span class="n">apply</span> <span class="n">le_min</span> <span class="bp">·</span> <span class="n">apply</span> <span class="n">min_le_right</span> <span class="n">apply</span> <span class="n">min_le_left</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">le_antisymm</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="k">show</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">a</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">le_min</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">min_le_right</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">min_le_left</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="k">show</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">le_min</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">min_le_right</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">min_le_left</span> </pre></div> </div> <p id="index-22">Here we have used dots to separate proofs of
-
@@ -1037,15 +1038,15 @@ <p>It may bother you that the proof is repetitive.To foreshadow skills you will learn later on, we note that one way to avoid the repetition is to state a local lemma and then use it:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">min</span> <span class="n">a</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">min</span> <span class="n">b</span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="k">have</span> <span class="n">h</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">,</span> <span class="n">min</span> <span class="n">x</span> <span class="n">y</span> <span class="bp">≤</span> <span class="n">min</span> <span class="n">y</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">x</span> <span class="n">y</span> <span class="n">apply</span> <span class="n">le_min</span> <span class="n">apply</span> <span class="n">min_le_right</span> <span class="n">apply</span> <span class="n">min_le_left</span> <span class="n">apply</span> <span class="n">le_antisymm</span> <span class="n">apply</span> <span class="n">h</span> <span class="n">apply</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">le_min</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">min_le_right</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">min_le_left</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">le_antisymm</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>We will say more about the universal quantifier in
-
@@ -1060,20 +1061,20 @@ uses <code class="docutils literal notranslate"><span class="pre">h</span> <span class="pre">a</span> <span class="pre">b</span></code>, whereas the second one uses <code class="docutils literal notranslate"><span class="pre">h</span> <span class="pre">b</span> <span class="pre">a</span></code>.</p><p id="index-23">Another solution is to use the <code class="docutils literal notranslate"><span class="pre">repeat</span></code> tactic, which applies a tactic (or a block) as many times as it can.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">min</span> <span class="n">a</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">min</span> <span class="n">b</span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">le_antisymm</span> <span class="n">repeat</span> <span class="n">apply</span> <span class="n">le_min</span> <span class="n">apply</span> <span class="n">min_le_right</span> <span class="n">apply</span> <span class="n">min_le_left</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">le_antisymm</span> <span class="w"> </span><span class="n">repeat</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">le_min</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">min_le_right</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">min_le_left</span> </pre></div> </div> <p>We encourage you to prove the following as exercises. You can use either of the tricks just described to shorten the first.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">max</span> <span class="n">a</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">max</span> <span class="n">b</span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">min</span> <span class="o">(</span><span class="n">min</span> <span class="n">a</span> <span class="n">b</span><span class="o">)</span> <span class="n">c</span> <span class="bp">=</span> <span class="n">min</span> <span class="n">a</span> <span class="o">(</span><span class="n">min</span> <span class="n">b</span> <span class="n">c</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">max</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">max</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="o">(</span><span class="n">min</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">(</span><span class="n">min</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Of course, you are welcome to prove the associativity of <code class="docutils literal notranslate"><span class="pre">max</span></code> as well.</p>
-
@@ -1096,10 +1097,10 @@ and in the second case, we have <code class="docutils literal notranslate"><span class="pre">min</span> <span class="pre">x</span> <span class="pre">y</span> <span class="pre">=</span> <span class="pre">y</span></code>.We will learn how to reason by cases in <a class="reference internal" href="C03_Logic.html#disjunction"><span class="std std-numref">Section 3.5</span></a>, but for now we will stick to examples that don’t require the case split.</p> <p>Here is one such example:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">aux</span> <span class="o">:</span> <span class="n">min</span> <span class="n">a</span> <span class="n">b</span> <span class="bp">+</span> <span class="n">c</span> <span class="bp">≤</span> <span class="n">min</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">c</span><span class="o">)</span> <span class="o">(</span><span class="n">b</span> <span class="bp">+</span> <span class="n">c</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">min</span> <span class="n">a</span> <span class="n">b</span> <span class="bp">+</span> <span class="n">c</span> <span class="bp">=</span> <span class="n">min</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">c</span><span class="o">)</span> <span class="o">(</span><span class="n">b</span> <span class="bp">+</span> <span class="n">c</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">aux</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">min</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>It is clear that <code class="docutils literal notranslate"><span class="pre">aux</span></code> provides one of the two inequalities
-
@@ -1110,12 +1111,12 @@ As a hint, you can use the theorem <code class="docutils literal notranslate"><span class="pre">add_neg_cancel_right</span></code>and the <code class="docutils literal notranslate"><span class="pre">linarith</span></code> tactic.</p> <p id="index-24">Lean’s naming convention is made manifest in the library’s name for the triangle inequality:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="o">(</span><span class="n">abs_add</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">,</span> <span class="bp">|</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="bp">|</span> <span class="bp">≤</span> <span class="bp">|</span><span class="n">a</span><span class="bp">|</span> <span class="bp">+</span> <span class="bp">|</span><span class="n">b</span><span class="bp">|</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">abs_add</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="bp">|</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="bp">|</span><span class="n">b</span><span class="bp">|</span><span class="o">)</span> </pre></div> </div> <p>Use it to prove the following variant, using also <code class="docutils literal notranslate"><span class="pre">add_sub_cancel_right</span></code>:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="bp">|</span><span class="n">a</span><span class="bp">|</span> <span class="bp">-</span> <span class="bp">|</span><span class="n">b</span><span class="bp">|</span> <span class="bp">≤</span> <span class="bp">|</span><span class="n">a</span> <span class="bp">-</span> <span class="n">b</span><span class="bp">|</span> <span class="o">:=</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="bp">|</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="bp">|</span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">end</span> </pre></div> </div>
-
@@ -1130,15 +1131,15 @@ Rather, it is a unicode character obtained bytyping <code class="docutils literal notranslate"><span class="pre">\|</span></code> in VS Code. By convention, Mathlib uses <code class="docutils literal notranslate"><span class="pre">dvd</span></code> to refer to it in theorem names.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h₀</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∣</span> <span class="n">y</span><span class="o">)</span> <span class="o">(</span><span class="n">h₁</span> <span class="o">:</span> <span class="n">y</span> <span class="bp">∣</span> <span class="n">z</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∣</span> <span class="n">z</span> <span class="o">:=</span> <span class="n">dvd_trans</span> <span class="n">h₀</span> <span class="n">h₁</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">z</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">dvd_trans</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∣</span> <span class="n">y</span> <span class="bp">*</span> <span class="n">x</span> <span class="bp">*</span> <span class="n">z</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">dvd_mul_of_dvd_left</span> <span class="n">apply</span> <span class="n">dvd_mul_left</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">dvd_mul_of_dvd_left</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">dvd_mul_left</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∣</span> <span class="n">x</span> <span class="bp">^</span> <span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">dvd_mul_left</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">dvd_mul_left</span> </pre></div> </div> <p>In the last example, the exponent is a natural
-
@@ -1147,8 +1148,8 @@ forces Lean to expand the definition of <code class="docutils literal notranslate"><span class="pre">x^2</span></code> to<code class="docutils literal notranslate"><span class="pre">x^1</span> <span class="pre">*</span> <span class="pre">x</span></code>. See if you can guess the names of the theorems you need to prove the following:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∣</span> <span class="n">w</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∣</span> <span class="n">y</span> <span class="bp">*</span> <span class="o">(</span><span class="n">x</span> <span class="bp">*</span> <span class="n">z</span><span class="o">)</span> <span class="bp">+</span> <span class="n">x</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="n">w</span> <span class="bp">^</span> <span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">w</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">z</span><span class="o">)</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">end</span> </pre></div> </div>
-
@@ -1157,18 +1158,18 @@ <code class="docutils literal notranslate"><span class="pre">gcd</span></code>, and least common multiple, <code class="docutils literal notranslate"><span class="pre">lcm</span></code>,are analogous to <code class="docutils literal notranslate"><span class="pre">min</span></code> and <code class="docutils literal notranslate"><span class="pre">max</span></code>. Since every number divides <code class="docutils literal notranslate"><span class="pre">0</span></code>, <code class="docutils literal notranslate"><span class="pre">0</span></code> is really the greatest element with respect to divisibility:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">(</span><span class="n">m</span> <span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">Nat.gcd_zero_right</span> <span class="n">n</span> <span class="o">:</span> <span class="n">Nat.gcd</span> <span class="n">n</span> <span class="mi">0</span> <span class="bp">=</span> <span class="n">n</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">Nat.gcd_zero_left</span> <span class="n">n</span> <span class="o">:</span> <span class="n">Nat.gcd</span> <span class="mi">0</span> <span class="n">n</span> <span class="bp">=</span> <span class="n">n</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">Nat.lcm_zero_right</span> <span class="n">n</span> <span class="o">:</span> <span class="n">Nat.lcm</span> <span class="n">n</span> <span class="mi">0</span> <span class="bp">=</span> <span class="mi">0</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">Nat.lcm_zero_left</span> <span class="n">n</span> <span class="o">:</span> <span class="n">Nat.lcm</span> <span class="mi">0</span> <span class="n">n</span> <span class="bp">=</span> <span class="mi">0</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">Nat.gcd_zero_right</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat.gcd</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">n</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">Nat.gcd_zero_left</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat.gcd</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">n</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">Nat.lcm_zero_right</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat.lcm</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">Nat.lcm_zero_left</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat.lcm</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span> </pre></div> </div> <p>See if you can guess the names of the theorems you will need to prove the following:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">Nat.gcd</span> <span class="n">m</span> <span class="n">n</span> <span class="bp">=</span> <span class="n">Nat.gcd</span> <span class="n">n</span> <span class="n">m</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat.gcd</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">Nat.gcd</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Hint: you can use <code class="docutils literal notranslate"><span class="pre">dvd_antisymm</span></code>, but if you do, Lean will
-
@@ -1190,13 +1191,13 @@ For example, a <em>partial order</em> consists of a set with abinary relation that is reflexive, transitive, and antisymmetric. like <code class="docutils literal notranslate"><span class="pre">≤</span></code> on the real numbers. Lean knows about partial orders:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">PartialOrder</span> <span class="n">α</span><span class="o">]</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="n">z</span> <span class="o">:</span> <span class="n">α</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">PartialOrder</span><span class="w"> </span><span class="n">α</span><span class="o">]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span> <span class="k">#check</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="k">#check</span> <span class="o">(</span><span class="n">le_refl</span> <span class="n">x</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">x</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">le_trans</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">→</span> <span class="n">y</span> <span class="bp">≤</span> <span class="n">z</span> <span class="bp">→</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">z</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">le_antisymm</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">→</span> <span class="n">y</span> <span class="bp">≤</span> <span class="n">x</span> <span class="bp">→</span> <span class="n">x</span> <span class="bp">=</span> <span class="n">y</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">le_refl</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">le_trans</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">z</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">le_antisymm</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">y</span><span class="o">)</span> </pre></div> </div> <p>Here we are adopting the Mathlib convention of using
-
@@ -1215,14 +1216,14 @@ which acts somewhat like <code class="docutils literal notranslate"><span class="pre"><</span></code> on the real numbers.Saying that <code class="docutils literal notranslate"><span class="pre">x</span></code> is less than <code class="docutils literal notranslate"><span class="pre">y</span></code> in this order is equivalent to saying that it is less-than-or-equal to <code class="docutils literal notranslate"><span class="pre">y</span></code> and not equal to <code class="docutils literal notranslate"><span class="pre">y</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="n">x</span> <span class="bp"><</span> <span class="n">y</span> <span class="k">#check</span> <span class="o">(</span><span class="n">lt_irrefl</span> <span class="n">x</span> <span class="o">:</span> <span class="bp">¬</span> <span class="o">(</span><span class="n">x</span> <span class="bp"><</span> <span class="n">x</span><span class="o">))</span> <span class="k">#check</span> <span class="o">(</span><span class="n">lt_trans</span> <span class="o">:</span> <span class="n">x</span> <span class="bp"><</span> <span class="n">y</span> <span class="bp">→</span> <span class="n">y</span> <span class="bp"><</span> <span class="n">z</span> <span class="bp">→</span> <span class="n">x</span> <span class="bp"><</span> <span class="n">z</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">lt_of_le_of_lt</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">→</span> <span class="n">y</span> <span class="bp"><</span> <span class="n">z</span> <span class="bp">→</span> <span class="n">x</span> <span class="bp"><</span> <span class="n">z</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">lt_of_lt_of_le</span> <span class="o">:</span> <span class="n">x</span> <span class="bp"><</span> <span class="n">y</span> <span class="bp">→</span> <span class="n">y</span> <span class="bp">≤</span> <span class="n">z</span> <span class="bp">→</span> <span class="n">x</span> <span class="bp"><</span> <span class="n">z</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">lt_irrefl</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">x</span><span class="o">))</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">lt_trans</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">z</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">lt_of_le_of_lt</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">z</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">lt_of_lt_of_le</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">z</span><span class="o">)</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">x</span> <span class="bp"><</span> <span class="n">y</span> <span class="bp">↔</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp">≠</span> <span class="n">y</span> <span class="o">:=</span> <span class="n">lt_iff_le_and_ne</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">lt_iff_le_and_ne</span> </pre></div> </div> <p>In this example, the symbol <code class="docutils literal notranslate"><span class="pre">∧</span></code> stands for “and,”
-
@@ -1234,17 +1235,17 @@ has the properties indicated.</p><p id="index-28">A <em>lattice</em> is a structure that extends a partial order with operations <code class="docutils literal notranslate"><span class="pre">⊓</span></code> and <code class="docutils literal notranslate"><span class="pre">⊔</span></code> that are analogous to <code class="docutils literal notranslate"><span class="pre">min</span></code> and <code class="docutils literal notranslate"><span class="pre">max</span></code> on the real numbers:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Lattice</span> <span class="n">α</span><span class="o">]</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="n">z</span> <span class="o">:</span> <span class="n">α</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Lattice</span><span class="w"> </span><span class="n">α</span><span class="o">]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span> <span class="k">#check</span> <span class="n">x</span> <span class="bp">⊓</span> <span class="n">y</span> <span class="k">#check</span> <span class="o">(</span><span class="n">inf_le_left</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">⊓</span> <span class="n">y</span> <span class="bp">≤</span> <span class="n">x</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">inf_le_right</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">⊓</span> <span class="n">y</span> <span class="bp">≤</span> <span class="n">y</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">le_inf</span> <span class="o">:</span> <span class="n">z</span> <span class="bp">≤</span> <span class="n">x</span> <span class="bp">→</span> <span class="n">z</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">→</span> <span class="n">z</span> <span class="bp">≤</span> <span class="n">x</span> <span class="bp">⊓</span> <span class="n">y</span><span class="o">)</span> <span class="k">#check</span> <span class="n">x</span> <span class="bp">⊔</span> <span class="n">y</span> <span class="k">#check</span> <span class="o">(</span><span class="n">le_sup_left</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">x</span> <span class="bp">⊔</span> <span class="n">y</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">le_sup_right</span> <span class="o">:</span> <span class="n">y</span> <span class="bp">≤</span> <span class="n">x</span> <span class="bp">⊔</span> <span class="n">y</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">sup_le</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">z</span> <span class="bp">→</span> <span class="n">y</span> <span class="bp">≤</span> <span class="n">z</span> <span class="bp">→</span> <span class="n">x</span> <span class="bp">⊔</span> <span class="n">y</span> <span class="bp">≤</span> <span class="n">z</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">y</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">inf_le_left</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">inf_le_right</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">le_inf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">y</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">y</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">le_sup_left</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">y</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">le_sup_right</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">y</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">sup_le</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">z</span><span class="o">)</span> </pre></div> </div> <p>The characterizations of <code class="docutils literal notranslate"><span class="pre">⊓</span></code> and <code class="docutils literal notranslate"><span class="pre">⊔</span></code> justify calling them
-
@@ -1299,28 +1300,28 @@ <code class="docutils literal notranslate"><span class="pre">y</span> <span class="pre">≤</span> <span class="pre">z</span></code>.Of course you can also avoid this issue by providing directly a full proof such as <code class="docutils literal notranslate"><span class="pre">exact</span> <span class="pre">le_trans</span> <span class="pre">inf_le_left</span> <span class="pre">inf_le_right</span></code>, but this requires a lot more planning.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">⊓</span> <span class="n">y</span> <span class="bp">=</span> <span class="n">y</span> <span class="bp">⊓</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">⊓</span> <span class="n">y</span> <span class="bp">⊓</span> <span class="n">z</span> <span class="bp">=</span> <span class="n">x</span> <span class="bp">⊓</span> <span class="o">(</span><span class="n">y</span> <span class="bp">⊓</span> <span class="n">z</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="o">(</span><span class="n">y</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">z</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">⊔</span> <span class="n">y</span> <span class="bp">=</span> <span class="n">y</span> <span class="bp">⊔</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">⊔</span> <span class="n">y</span> <span class="bp">⊔</span> <span class="n">z</span> <span class="bp">=</span> <span class="n">x</span> <span class="bp">⊔</span> <span class="o">(</span><span class="n">y</span> <span class="bp">⊔</span> <span class="n">z</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="o">(</span><span class="n">y</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">z</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>You can find these theorems in the Mathlib as <code class="docutils literal notranslate"><span class="pre">inf_comm</span></code>, <code class="docutils literal notranslate"><span class="pre">inf_assoc</span></code>, <code class="docutils literal notranslate"><span class="pre">sup_comm</span></code>, and <code class="docutils literal notranslate"><span class="pre">sup_assoc</span></code>, respectively.</p> <p>Another good exercise is to prove the <em>absorption laws</em> using only those axioms:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">absorb1</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">⊓</span> <span class="o">(</span><span class="n">x</span> <span class="bp">⊔</span> <span class="n">y</span><span class="o">)</span> <span class="bp">=</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">absorb1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">theorem</span> <span class="n">absorb2</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">⊔</span> <span class="n">x</span> <span class="bp">⊓</span> <span class="n">y</span> <span class="bp">=</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">absorb2</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>These can be found in Mathlib with the names <code class="docutils literal notranslate"><span class="pre">inf_sup_self</span></code> and <code class="docutils literal notranslate"><span class="pre">sup_inf_self</span></code>.</p>
-
@@ -1328,13 +1329,13 @@ <p>A lattice that satisfies the additional identities<code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">⊓</span> <span class="pre">(y</span> <span class="pre">⊔</span> <span class="pre">z)</span> <span class="pre">=</span> <span class="pre">(x</span> <span class="pre">⊓</span> <span class="pre">y)</span> <span class="pre">⊔</span> <span class="pre">(x</span> <span class="pre">⊓</span> <span class="pre">z)</span></code> and <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">⊔</span> <span class="pre">(y</span> <span class="pre">⊓</span> <span class="pre">z)</span> <span class="pre">=</span> <span class="pre">(x</span> <span class="pre">⊔</span> <span class="pre">y)</span> <span class="pre">⊓</span> <span class="pre">(x</span> <span class="pre">⊔</span> <span class="pre">z)</span></code> is called a <em>distributive lattice</em>. Lean knows about these too:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">DistribLattice</span> <span class="n">α</span><span class="o">]</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="n">z</span> <span class="o">:</span> <span class="n">α</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">DistribLattice</span><span class="w"> </span><span class="n">α</span><span class="o">]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">inf_sup_left</span> <span class="n">x</span> <span class="n">y</span> <span class="n">z</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">⊓</span> <span class="o">(</span><span class="n">y</span> <span class="bp">⊔</span> <span class="n">z</span><span class="o">)</span> <span class="bp">=</span> <span class="n">x</span> <span class="bp">⊓</span> <span class="n">y</span> <span class="bp">⊔</span> <span class="n">x</span> <span class="bp">⊓</span> <span class="n">z</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">inf_sup_right</span> <span class="n">x</span> <span class="n">y</span> <span class="n">z</span> <span class="o">:</span> <span class="o">(</span><span class="n">x</span> <span class="bp">⊔</span> <span class="n">y</span><span class="o">)</span> <span class="bp">⊓</span> <span class="n">z</span> <span class="bp">=</span> <span class="n">x</span> <span class="bp">⊓</span> <span class="n">z</span> <span class="bp">⊔</span> <span class="n">y</span> <span class="bp">⊓</span> <span class="n">z</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">sup_inf_left</span> <span class="n">x</span> <span class="n">y</span> <span class="n">z</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">⊔</span> <span class="n">y</span> <span class="bp">⊓</span> <span class="n">z</span> <span class="bp">=</span> <span class="o">(</span><span class="n">x</span> <span class="bp">⊔</span> <span class="n">y</span><span class="o">)</span> <span class="bp">⊓</span> <span class="o">(</span><span class="n">x</span> <span class="bp">⊔</span> <span class="n">z</span><span class="o">))</span> <span class="k">#check</span> <span class="o">(</span><span class="n">sup_inf_right</span> <span class="n">x</span> <span class="n">y</span> <span class="n">z</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">⊓</span> <span class="n">y</span> <span class="bp">⊔</span> <span class="n">z</span> <span class="bp">=</span> <span class="o">(</span><span class="n">x</span> <span class="bp">⊔</span> <span class="n">z</span><span class="o">)</span> <span class="bp">⊓</span> <span class="o">(</span><span class="n">y</span> <span class="bp">⊔</span> <span class="n">z</span><span class="o">))</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">inf_sup_left</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="o">(</span><span class="n">y</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">z</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">z</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">inf_sup_right</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">z</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">sup_inf_left</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">z</span><span class="o">))</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">sup_inf_right</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">z</span><span class="o">)</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="o">(</span><span class="n">y</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">z</span><span class="o">))</span> </pre></div> </div> <p>The left and right versions are easily shown to be
-
@@ -1345,14 +1346,14 @@ by providing an explicit description of anondistributive lattice with finitely many elements. It is also a good exercise to show that in any lattice, either distributivity law implies the other:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Lattice</span> <span class="n">α</span><span class="o">]</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">α</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Lattice</span><span class="w"> </span><span class="n">α</span><span class="o">]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="n">y</span> <span class="n">z</span> <span class="o">:</span> <span class="n">α</span><span class="o">,</span> <span class="n">x</span> <span class="bp">⊓</span> <span class="o">(</span><span class="n">y</span> <span class="bp">⊔</span> <span class="n">z</span><span class="o">)</span> <span class="bp">=</span> <span class="n">x</span> <span class="bp">⊓</span> <span class="n">y</span> <span class="bp">⊔</span> <span class="n">x</span> <span class="bp">⊓</span> <span class="n">z</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">⊔</span> <span class="n">b</span> <span class="bp">⊓</span> <span class="n">c</span> <span class="bp">=</span> <span class="o">(</span><span class="n">a</span> <span class="bp">⊔</span> <span class="n">b</span><span class="o">)</span> <span class="bp">⊓</span> <span class="o">(</span><span class="n">a</span> <span class="bp">⊔</span> <span class="n">c</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="o">(</span><span class="n">y</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">z</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">z</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="n">y</span> <span class="n">z</span> <span class="o">:</span> <span class="n">α</span><span class="o">,</span> <span class="n">x</span> <span class="bp">⊔</span> <span class="n">y</span> <span class="bp">⊓</span> <span class="n">z</span> <span class="bp">=</span> <span class="o">(</span><span class="n">x</span> <span class="bp">⊔</span> <span class="n">y</span><span class="o">)</span> <span class="bp">⊓</span> <span class="o">(</span><span class="n">x</span> <span class="bp">⊔</span> <span class="n">z</span><span class="o">))</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">⊓</span> <span class="o">(</span><span class="n">b</span> <span class="bp">⊔</span> <span class="n">c</span><span class="o">)</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">⊓</span> <span class="n">b</span> <span class="bp">⊔</span> <span class="n">a</span> <span class="bp">⊓</span> <span class="n">c</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">z</span><span class="o">))</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>It is possible to combine axiomatic structures into larger ones.
-
@@ -1360,16 +1361,16 @@ For example, a <em>strict ordered ring</em> consists of a ring togetherwith a partial order on the carrier satisfying additional axioms that say that the ring operations are compatible with the order:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">StrictOrderedRing</span> <span class="n">R</span><span class="o">]</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">StrictOrderedRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">add_le_add_left</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">→</span> <span class="bp">∀</span> <span class="n">c</span><span class="o">,</span> <span class="n">c</span> <span class="bp">+</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">c</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">mul_pos</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">a</span> <span class="bp">→</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">b</span> <span class="bp">→</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">add_le_add_left</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">c</span><span class="o">,</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">mul_pos</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> </pre></div> </div> <p><a class="reference internal" href="C03_Logic.html#logic"><span class="std std-numref">Chapter 3</span></a> will provide the means to derive the following from <code class="docutils literal notranslate"><span class="pre">mul_pos</span></code> and the definition of <code class="docutils literal notranslate"><span class="pre"><</span></code>:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="o">(</span><span class="n">mul_nonneg</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">a</span> <span class="bp">→</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">→</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">mul_nonneg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> </pre></div> </div> <p>It is then an extended exercise to show that many common facts
-
@@ -1379,14 +1380,14 @@ Here are a couple of examples you can try,using only properties of rings, partial orders, and the facts enumerated in the last two examples (beware that those rings are not assumed to be commutative, so the <cite>ring</cite> tactic is not available):</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span><span class="o">)</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">-</span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span><span class="o">:</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">-</span> <span class="n">a</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span><span class="o">)</span> <span class="o">(</span><span class="n">h'</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">c</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">c</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">c</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p id="index-30">Finally, here is one last example.
-
@@ -1394,19 +1395,19 @@ A <em>metric space</em> consists of a set equipped with a notion ofdistance, <code class="docutils literal notranslate"><span class="pre">dist</span> <span class="pre">x</span> <span class="pre">y</span></code>, mapping any pair of elements to a real number. The distance function is assumed to satisfy the following axioms:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">X</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">MetricSpace</span> <span class="n">X</span><span class="o">]</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="n">z</span> <span class="o">:</span> <span class="n">X</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">X</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">MetricSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">dist_self</span> <span class="n">x</span> <span class="o">:</span> <span class="n">dist</span> <span class="n">x</span> <span class="n">x</span> <span class="bp">=</span> <span class="mi">0</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">dist_comm</span> <span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">dist</span> <span class="n">x</span> <span class="n">y</span> <span class="bp">=</span> <span class="n">dist</span> <span class="n">y</span> <span class="n">x</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">dist_triangle</span> <span class="n">x</span> <span class="n">y</span> <span class="n">z</span> <span class="o">:</span> <span class="n">dist</span> <span class="n">x</span> <span class="n">z</span> <span class="bp">≤</span> <span class="n">dist</span> <span class="n">x</span> <span class="n">y</span> <span class="bp">+</span> <span class="n">dist</span> <span class="n">y</span> <span class="n">z</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">dist_self</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">dist_comm</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">x</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">dist_triangle</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="o">)</span> </pre></div> </div> <p>Having mastered this section, you can show that it follows from these axioms that distances are always nonnegative:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">X</span><span class="o">)</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">dist</span> <span class="n">x</span> <span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>We recommend making use of the theorem <code class="docutils literal notranslate"><span class="pre">nonneg_of_mul_nonneg_left</span></code>.
-
-
-
@@ -1,3 +1,5 @@<!DOCTYPE html> <html class="writer-html5" lang="en" data-content_root="./"> <head>
-
@@ -6,18 +8,17 @@<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>3. Logic — Mathematics in Lean 0.1 documentation</title> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=80d5e7a1" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=86f27845" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" /> <link rel="stylesheet" type="text/css" href="_static/css/custom.css?v=0731ccc3" /> <link rel="shortcut icon" href="_static/favicon.ico"/> <script src="_static/jquery.js?v=8dae8fb0"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=888ff710"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> <script src="_static/jquery.js?v=5d32c60e"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=9bcbadda"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> <script src="_static/js/theme.js"></script> <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" />
-
@@ -108,13 +109,13 @@ that are built up in this way.</p><section id="implication-and-the-universal-quantifier"> <span id="id2"></span><h2><span class="section-number">3.1. </span>Implication and the Universal Quantifier<a class="headerlink" href="#implication-and-the-universal-quantifier" title="Link to this heading"></a></h2> <p>Consider the statement after the <code class="docutils literal notranslate"><span class="pre">#check</span></code>:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="bp">∀</span> <span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">,</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">x</span> <span class="bp">→</span> <span class="bp">|</span><span class="n">x</span><span class="bp">|</span> <span class="bp">=</span> <span class="n">x</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span> </pre></div> </div> <p>In words, we would say “for every real number <code class="docutils literal notranslate"><span class="pre">x</span></code>, if <code class="docutils literal notranslate"><span class="pre">0</span> <span class="pre">≤</span> <span class="pre">x</span></code> then the absolute value of <code class="docutils literal notranslate"><span class="pre">x</span></code> equals <code class="docutils literal notranslate"><span class="pre">x</span></code>”. We can also have more complicated statements like:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="bp">∀</span> <span class="n">x</span> <span class="n">y</span> <span class="n">ε</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">,</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">ε</span> <span class="bp">→</span> <span class="n">ε</span> <span class="bp">≤</span> <span class="mi">1</span> <span class="bp">→</span> <span class="bp">|</span><span class="n">x</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">ε</span> <span class="bp">→</span> <span class="bp">|</span><span class="n">y</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">ε</span> <span class="bp">→</span> <span class="bp">|</span><span class="n">x</span> <span class="bp">*</span> <span class="n">y</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">ε</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span> </pre></div> </div> <p>In words, we would say “for every <code class="docutils literal notranslate"><span class="pre">x</span></code>, <code class="docutils literal notranslate"><span class="pre">y</span></code>, and <code class="docutils literal notranslate"><span class="pre">ε</span></code>,
-
@@ -135,17 +136,17 @@ In particular, if you have proved a theorem of that form,you can apply it to objects and hypotheses in the same way. We will use as an example the following statement that we will help you to prove a bit later:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">my_lemma</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="n">y</span> <span class="n">ε</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">,</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">ε</span> <span class="bp">→</span> <span class="n">ε</span> <span class="bp">≤</span> <span class="mi">1</span> <span class="bp">→</span> <span class="bp">|</span><span class="n">x</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">ε</span> <span class="bp">→</span> <span class="bp">|</span><span class="n">y</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">ε</span> <span class="bp">→</span> <span class="bp">|</span><span class="n">x</span> <span class="bp">*</span> <span class="n">y</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">ε</span> <span class="o">:=</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">my_lemma</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kn">section</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">δ</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">h₀</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">δ</span><span class="o">)</span> <span class="o">(</span><span class="n">h₁</span> <span class="o">:</span> <span class="n">δ</span> <span class="bp">≤</span> <span class="mi">1</span><span class="o">)</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">ha</span> <span class="o">:</span> <span class="bp">|</span><span class="n">a</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">δ</span><span class="o">)</span> <span class="o">(</span><span class="n">hb</span> <span class="o">:</span> <span class="bp">|</span><span class="n">b</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">δ</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">δ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">δ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">δ</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">ha</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">δ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hb</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">δ</span><span class="o">)</span> <span class="k">#check</span> <span class="n">my_lemma</span> <span class="n">a</span> <span class="n">b</span> <span class="n">δ</span> <span class="k">#check</span> <span class="n">my_lemma</span> <span class="n">a</span> <span class="n">b</span> <span class="n">δ</span> <span class="n">h₀</span> <span class="n">h₁</span> <span class="k">#check</span> <span class="n">my_lemma</span> <span class="n">a</span> <span class="n">b</span> <span class="n">δ</span> <span class="n">h₀</span> <span class="n">h₁</span> <span class="n">ha</span> <span class="n">hb</span> <span class="k">#check</span><span class="w"> </span><span class="n">my_lemma</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">δ</span> <span class="k">#check</span><span class="w"> </span><span class="n">my_lemma</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">δ</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span> <span class="k">#check</span><span class="w"> </span><span class="n">my_lemma</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">δ</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="n">ha</span><span class="w"> </span><span class="n">hb</span> <span class="kd">end</span> </pre></div>
-
@@ -155,15 +156,15 @@ to use curly brackets to make quantified variables implicitwhen they can be inferred from subsequent hypotheses. When we do that, we can just apply a lemma to the hypotheses without mentioning the objects.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">my_lemma2</span> <span class="o">:</span> <span class="bp">∀</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="n">ε</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">},</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">ε</span> <span class="bp">→</span> <span class="n">ε</span> <span class="bp">≤</span> <span class="mi">1</span> <span class="bp">→</span> <span class="bp">|</span><span class="n">x</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">ε</span> <span class="bp">→</span> <span class="bp">|</span><span class="n">y</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">ε</span> <span class="bp">→</span> <span class="bp">|</span><span class="n">x</span> <span class="bp">*</span> <span class="n">y</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">ε</span> <span class="o">:=</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">my_lemma2</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">},</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kn">section</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">δ</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">h₀</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">δ</span><span class="o">)</span> <span class="o">(</span><span class="n">h₁</span> <span class="o">:</span> <span class="n">δ</span> <span class="bp">≤</span> <span class="mi">1</span><span class="o">)</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">ha</span> <span class="o">:</span> <span class="bp">|</span><span class="n">a</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">δ</span><span class="o">)</span> <span class="o">(</span><span class="n">hb</span> <span class="o">:</span> <span class="bp">|</span><span class="n">b</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">δ</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">δ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">δ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">δ</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">ha</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">δ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hb</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">δ</span><span class="o">)</span> <span class="k">#check</span> <span class="n">my_lemma2</span> <span class="n">h₀</span> <span class="n">h₁</span> <span class="n">ha</span> <span class="n">hb</span> <span class="k">#check</span><span class="w"> </span><span class="n">my_lemma2</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="n">ha</span><span class="w"> </span><span class="n">hb</span> <span class="kd">end</span> </pre></div>
-
@@ -175,10 +176,10 @@ you are left with new goals that require you to proveeach of the hypotheses.</p> <p id="index-0">To prove a statement like this, use the <code class="docutils literal notranslate"><span class="pre">intro</span></code> tactic. Take a look at what it does in this example:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">my_lemma3</span> <span class="o">:</span> <span class="bp">∀</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="n">ε</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">},</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">ε</span> <span class="bp">→</span> <span class="n">ε</span> <span class="bp">≤</span> <span class="mi">1</span> <span class="bp">→</span> <span class="bp">|</span><span class="n">x</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">ε</span> <span class="bp">→</span> <span class="bp">|</span><span class="n">y</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">ε</span> <span class="bp">→</span> <span class="bp">|</span><span class="n">x</span> <span class="bp">*</span> <span class="n">y</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">ε</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">x</span> <span class="n">y</span> <span class="n">ε</span> <span class="n">epos</span> <span class="n">ele1</span> <span class="n">xlt</span> <span class="n">ylt</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">my_lemma3</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">},</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="n">epos</span><span class="w"> </span><span class="n">ele1</span><span class="w"> </span><span class="n">xlt</span><span class="w"> </span><span class="n">ylt</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>We can use any names we want for the universally quantified variables;
-
@@ -196,14 +197,14 @@ as we did in the last section.In a moment, we will see why it is sometimes necessary to introduce variables and hypotheses after the proof begins.</p> <p>To help you prove the lemma, we will start you off:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">my_lemma4</span> <span class="o">:</span> <span class="bp">∀</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="n">ε</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">},</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">ε</span> <span class="bp">→</span> <span class="n">ε</span> <span class="bp">≤</span> <span class="mi">1</span> <span class="bp">→</span> <span class="bp">|</span><span class="n">x</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">ε</span> <span class="bp">→</span> <span class="bp">|</span><span class="n">y</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">ε</span> <span class="bp">→</span> <span class="bp">|</span><span class="n">x</span> <span class="bp">*</span> <span class="n">y</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">ε</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">x</span> <span class="n">y</span> <span class="n">ε</span> <span class="n">epos</span> <span class="n">ele1</span> <span class="n">xlt</span> <span class="n">ylt</span> <span class="k">calc</span> <span class="bp">|</span><span class="n">x</span> <span class="bp">*</span> <span class="n">y</span><span class="bp">|</span> <span class="bp">=</span> <span class="bp">|</span><span class="n">x</span><span class="bp">|</span> <span class="bp">*</span> <span class="bp">|</span><span class="n">y</span><span class="bp">|</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">_</span> <span class="bp">≤</span> <span class="bp">|</span><span class="n">x</span><span class="bp">|</span> <span class="bp">*</span> <span class="n">ε</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">_</span> <span class="bp"><</span> <span class="mi">1</span> <span class="bp">*</span> <span class="n">ε</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">_</span> <span class="bp">=</span> <span class="n">ε</span> <span class="o">:=</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">my_lemma4</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">},</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="n">epos</span><span class="w"> </span><span class="n">ele1</span><span class="w"> </span><span class="n">xlt</span><span class="w"> </span><span class="n">ylt</span> <span class="w"> </span><span class="k">calc</span> <span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Finish the proof using the theorems
-
@@ -224,22 +225,22 @@ The first says that <code class="docutils literal notranslate"><span class="pre">a</span></code> is an upper bound on thevalues of <code class="docutils literal notranslate"><span class="pre">f</span></code>, and the second says that <code class="docutils literal notranslate"><span class="pre">a</span></code> is a lower bound on the values of <code class="docutils literal notranslate"><span class="pre">f</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">FnUb</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="kt">Prop</span> <span class="o">:=</span> <span class="bp">∀</span> <span class="n">x</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">a</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">FnUb</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span> <span class="kd">def</span> <span class="n">FnLb</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="kt">Prop</span> <span class="o">:=</span> <span class="bp">∀</span> <span class="n">x</span><span class="o">,</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">f</span> <span class="n">x</span> <span class="kd">def</span><span class="w"> </span><span class="n">FnLb</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span> </pre></div> </div> <p id="index-1">In the next example, <code class="docutils literal notranslate"><span class="pre">fun</span> <span class="pre">x</span> <span class="pre">↦</span> <span class="pre">f</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">g</span> <span class="pre">x</span></code> is the function that maps <code class="docutils literal notranslate"><span class="pre">x</span></code> to <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">g</span> <span class="pre">x</span></code>. Going from the expression <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">g</span> <span class="pre">x</span></code> to this function is called a lambda abstraction in type theory.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">hfa</span> <span class="o">:</span> <span class="n">FnUb</span> <span class="n">f</span> <span class="n">a</span><span class="o">)</span> <span class="o">(</span><span class="n">hgb</span> <span class="o">:</span> <span class="n">FnUb</span> <span class="n">g</span> <span class="n">b</span><span class="o">)</span> <span class="o">:</span> <span class="n">FnUb</span> <span class="o">(</span><span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">g</span> <span class="n">x</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">x</span> <span class="n">dsimp</span> <span class="n">apply</span> <span class="n">add_le_add</span> <span class="n">apply</span> <span class="n">hfa</span> <span class="n">apply</span> <span class="n">hgb</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">hfa</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnUb</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hgb</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnUb</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnUb</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="n">dsimp</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">add_le_add</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">hfa</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">hgb</span> </pre></div> </div> <p id="index-2">Applying <code class="docutils literal notranslate"><span class="pre">intro</span></code> to the goal <code class="docutils literal notranslate"><span class="pre">FnUb</span> <span class="pre">(fun</span> <span class="pre">x</span> <span class="pre">↦</span> <span class="pre">f</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">g</span> <span class="pre">x)</span> <span class="pre">(a</span> <span class="pre">+</span> <span class="pre">b)</span></code>
-
@@ -262,15 +263,15 @@ <p>The rest of the proof is routine.The last two <code class="docutils literal notranslate"><span class="pre">apply</span></code> commands force Lean to unfold the definitions of <code class="docutils literal notranslate"><span class="pre">FnUb</span></code> in the hypotheses. Try carrying out similar proofs of these:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">hfa</span> <span class="o">:</span> <span class="n">FnLb</span> <span class="n">f</span> <span class="n">a</span><span class="o">)</span> <span class="o">(</span><span class="n">hgb</span> <span class="o">:</span> <span class="n">FnLb</span> <span class="n">g</span> <span class="n">b</span><span class="o">)</span> <span class="o">:</span> <span class="n">FnLb</span> <span class="o">(</span><span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">g</span> <span class="n">x</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="o">:=</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">hfa</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnLb</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hgb</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnLb</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnLb</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">nnf</span> <span class="o">:</span> <span class="n">FnLb</span> <span class="n">f</span> <span class="mi">0</span><span class="o">)</span> <span class="o">(</span><span class="n">nng</span> <span class="o">:</span> <span class="n">FnLb</span> <span class="n">g</span> <span class="mi">0</span><span class="o">)</span> <span class="o">:</span> <span class="n">FnLb</span> <span class="o">(</span><span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">*</span> <span class="n">g</span> <span class="n">x</span><span class="o">)</span> <span class="mi">0</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">nnf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnLb</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">nng</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnLb</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnLb</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">hfa</span> <span class="o">:</span> <span class="n">FnUb</span> <span class="n">f</span> <span class="n">a</span><span class="o">)</span> <span class="o">(</span><span class="n">hgb</span> <span class="o">:</span> <span class="n">FnUb</span> <span class="n">g</span> <span class="n">b</span><span class="o">)</span> <span class="o">(</span><span class="n">nng</span> <span class="o">:</span> <span class="n">FnLb</span> <span class="n">g</span> <span class="mi">0</span><span class="o">)</span> <span class="o">(</span><span class="n">nna</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">a</span><span class="o">)</span> <span class="o">:</span> <span class="n">FnUb</span> <span class="o">(</span><span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">*</span> <span class="n">g</span> <span class="n">x</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">b</span><span class="o">)</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">hfa</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnUb</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hgb</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnUb</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">nng</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnLb</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">nna</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">FnUb</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Even though we have defined <code class="docutils literal notranslate"><span class="pre">FnUb</span></code> and <code class="docutils literal notranslate"><span class="pre">FnLb</span></code> for functions
-
@@ -286,15 +287,15 @@ but it is worth knowing that the natural numbers, integers, rationals,and real numbers are all instances. So if we prove the theorem <code class="docutils literal notranslate"><span class="pre">fnUb_add</span></code> at that level of generality, it will apply in all these instances.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">OrderedCancelAddCommMonoid</span> <span class="n">R</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">OrderedCancelAddCommMonoid</span><span class="w"> </span><span class="n">R</span><span class="o">]</span> <span class="k">#check</span> <span class="n">add_le_add</span> <span class="k">#check</span><span class="w"> </span><span class="n">add_le_add</span> <span class="kd">def</span> <span class="n">FnUb'</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">R</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="kt">Prop</span> <span class="o">:=</span> <span class="bp">∀</span> <span class="n">x</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">a</span> <span class="kd">def</span><span class="w"> </span><span class="n">FnUb'</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span> <span class="kd">theorem</span> <span class="n">fnUb_add</span> <span class="o">{</span><span class="n">f</span> <span class="n">g</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">R</span><span class="o">}</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">R</span><span class="o">}</span> <span class="o">(</span><span class="n">hfa</span> <span class="o">:</span> <span class="n">FnUb'</span> <span class="n">f</span> <span class="n">a</span><span class="o">)</span> <span class="o">(</span><span class="n">hgb</span> <span class="o">:</span> <span class="n">FnUb'</span> <span class="n">g</span> <span class="n">b</span><span class="o">)</span> <span class="o">:</span> <span class="n">FnUb'</span> <span class="o">(</span><span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">g</span> <span class="n">x</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">add_le_add</span> <span class="o">(</span><span class="n">hfa</span> <span class="n">x</span><span class="o">)</span> <span class="o">(</span><span class="n">hgb</span> <span class="n">x</span><span class="o">)</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">fnUb_add</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">R</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hfa</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnUb'</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hgb</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnUb'</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">FnUb'</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">add_le_add</span><span class="w"> </span><span class="o">(</span><span class="n">hfa</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hgb</span><span class="w"> </span><span class="n">x</span><span class="o">)</span> </pre></div> </div> <p>You have already seen square brackets like these in
-
@@ -307,8 +308,8 @@ that work at a high level of generality.</p><p id="index-3">For another example of a hidden universal quantifier, Mathlib defines a predicate <code class="docutils literal notranslate"><span class="pre">Monotone</span></code>, which says that a function is nondecreasing in its arguments:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">Monotone</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∀</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span><span class="o">},</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">→</span> <span class="n">f</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">f</span> <span class="n">b</span> <span class="o">:=</span> <span class="bp">@</span><span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="o">},</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="bp">@</span><span class="n">h</span> </pre></div> </div> <p>The property <code class="docutils literal notranslate"><span class="pre">Monotone</span> <span class="pre">f</span></code> is defined to be exactly the expression
-
@@ -324,11 +325,11 @@ and then apply the resulting expression to the goal.Or you can apply it to the goal and let Lean help you work backwards by displaying the remaining hypotheses as new subgoals.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">mf</span> <span class="o">:</span> <span class="n">Monotone</span> <span class="n">f</span><span class="o">)</span> <span class="o">(</span><span class="n">mg</span> <span class="o">:</span> <span class="n">Monotone</span> <span class="n">g</span><span class="o">)</span> <span class="o">:</span> <span class="n">Monotone</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">g</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">a</span> <span class="n">b</span> <span class="n">aleb</span> <span class="n">apply</span> <span class="n">add_le_add</span> <span class="n">apply</span> <span class="n">mf</span> <span class="n">aleb</span> <span class="n">apply</span> <span class="n">mg</span> <span class="n">aleb</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">mf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">mg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">aleb</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">add_le_add</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">mf</span><span class="w"> </span><span class="n">aleb</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">mg</span><span class="w"> </span><span class="n">aleb</span> </pre></div> </div> <p>When a proof is this short, it is often convenient
-
@@ -344,8 +345,8 @@ So the <code class="docutils literal notranslate"><span class="pre">intro</span></code> command in the previous proofcorresponds to the lambda abstraction in the next proof term. The <code class="docutils literal notranslate"><span class="pre">apply</span></code> commands then correspond to building the application of the theorem to its arguments.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">mf</span> <span class="o">:</span> <span class="n">Monotone</span> <span class="n">f</span><span class="o">)</span> <span class="o">(</span><span class="n">mg</span> <span class="o">:</span> <span class="n">Monotone</span> <span class="n">g</span><span class="o">)</span> <span class="o">:</span> <span class="n">Monotone</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">g</span> <span class="n">x</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">a</span> <span class="n">b</span> <span class="n">aleb</span> <span class="bp">↦</span> <span class="n">add_le_add</span> <span class="o">(</span><span class="n">mf</span> <span class="n">aleb</span><span class="o">)</span> <span class="o">(</span><span class="n">mg</span> <span class="n">aleb</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">mf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">mg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">aleb</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">add_le_add</span><span class="w"> </span><span class="o">(</span><span class="n">mf</span><span class="w"> </span><span class="n">aleb</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">mg</span><span class="w"> </span><span class="n">aleb</span><span class="o">)</span> </pre></div> </div> <p>Here is a useful trick: if you start writing
-
@@ -359,11 +360,11 @@ hover over the squiggly error marker,Lean will show you the goal that the remaining expression has to solve.</p> <p>Try proving these, with either tactics or proof terms:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">c</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">mf</span> <span class="o">:</span> <span class="n">Monotone</span> <span class="n">f</span><span class="o">)</span> <span class="o">(</span><span class="n">nnc</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">c</span><span class="o">)</span> <span class="o">:</span> <span class="n">Monotone</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">c</span> <span class="bp">*</span> <span class="n">f</span> <span class="n">x</span> <span class="o">:=</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">mf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">nnc</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">mf</span> <span class="o">:</span> <span class="n">Monotone</span> <span class="n">f</span><span class="o">)</span> <span class="o">(</span><span class="n">mg</span> <span class="o">:</span> <span class="n">Monotone</span> <span class="n">g</span><span class="o">)</span> <span class="o">:</span> <span class="n">Monotone</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="o">(</span><span class="n">g</span> <span class="n">x</span><span class="o">)</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">mf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">mg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Here are some more examples.
-
@@ -374,27 +375,27 @@ and <em>odd</em> if <span class="math notranslate nohighlight">\(f(-x) = -f(x)\)</span> for every <span class="math notranslate nohighlight">\(x\)</span>.The following example defines these two notions formally and establishes one fact about them. You can complete the proofs of the others.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">FnEven</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="kt">Prop</span> <span class="o">:=</span> <span class="bp">∀</span> <span class="n">x</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">=</span> <span class="n">f</span> <span class="o">(</span><span class="bp">-</span><span class="n">x</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">FnEven</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="bp">-</span><span class="n">x</span><span class="o">)</span> <span class="kd">def</span> <span class="n">FnOdd</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="kt">Prop</span> <span class="o">:=</span> <span class="bp">∀</span> <span class="n">x</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">=</span> <span class="bp">-</span><span class="n">f</span> <span class="o">(</span><span class="bp">-</span><span class="n">x</span><span class="o">)</span> <span class="kd">def</span><span class="w"> </span><span class="n">FnOdd</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">-</span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="bp">-</span><span class="n">x</span><span class="o">)</span> <span class="kd">example</span> <span class="o">(</span><span class="n">ef</span> <span class="o">:</span> <span class="n">FnEven</span> <span class="n">f</span><span class="o">)</span> <span class="o">(</span><span class="n">eg</span> <span class="o">:</span> <span class="n">FnEven</span> <span class="n">g</span><span class="o">)</span> <span class="o">:</span> <span class="n">FnEven</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">g</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">x</span> <span class="k">calc</span> <span class="o">(</span><span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">g</span> <span class="n">x</span><span class="o">)</span> <span class="n">x</span> <span class="bp">=</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">g</span> <span class="n">x</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="n">_</span> <span class="bp">=</span> <span class="n">f</span> <span class="o">(</span><span class="bp">-</span><span class="n">x</span><span class="o">)</span> <span class="bp">+</span> <span class="n">g</span> <span class="o">(</span><span class="bp">-</span><span class="n">x</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">ef</span><span class="o">,</span> <span class="n">eg</span><span class="o">]</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">ef</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnEven</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">eg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnEven</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnEven</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="k">calc</span> <span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">rfl</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="bp">-</span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">(</span><span class="bp">-</span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">ef</span><span class="o">,</span><span class="w"> </span><span class="n">eg</span><span class="o">]</span> <span class="kd">example</span> <span class="o">(</span><span class="n">of</span> <span class="o">:</span> <span class="n">FnOdd</span> <span class="n">f</span><span class="o">)</span> <span class="o">(</span><span class="n">og</span> <span class="o">:</span> <span class="n">FnOdd</span> <span class="n">g</span><span class="o">)</span> <span class="o">:</span> <span class="n">FnEven</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">*</span> <span class="n">g</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">of</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnOdd</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">og</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnOdd</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnEven</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">ef</span> <span class="o">:</span> <span class="n">FnEven</span> <span class="n">f</span><span class="o">)</span> <span class="o">(</span><span class="n">og</span> <span class="o">:</span> <span class="n">FnOdd</span> <span class="n">g</span><span class="o">)</span> <span class="o">:</span> <span class="n">FnOdd</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">*</span> <span class="n">g</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">ef</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnEven</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">og</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnOdd</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnOdd</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">ef</span> <span class="o">:</span> <span class="n">FnEven</span> <span class="n">f</span><span class="o">)</span> <span class="o">(</span><span class="n">og</span> <span class="o">:</span> <span class="n">FnOdd</span> <span class="n">g</span><span class="o">)</span> <span class="o">:</span> <span class="n">FnEven</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="o">(</span><span class="n">g</span> <span class="n">x</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">ef</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnEven</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">og</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnOdd</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnEven</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p id="index-4">The first proof can be shortened using <code class="docutils literal notranslate"><span class="pre">dsimp</span></code> or <code class="docutils literal notranslate"><span class="pre">change</span></code>
-
@@ -434,16 +435,16 @@ we can write <code class="docutils literal notranslate"><span class="pre">h</span> <span class="pre">h'</span></code> as justification for <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">∈</span> <span class="pre">t</span></code>.The following example provides a tactic proof and a proof term justifying the reflexivity of the subset relation, and asks you to do the same for transitivity.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">(</span><span class="n">r</span> <span class="n">s</span> <span class="n">t</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">α</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">)</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">⊆</span> <span class="n">s</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">x</span> <span class="n">xs</span> <span class="n">exact</span> <span class="n">xs</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">xs</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">xs</span> <span class="kd">theorem</span> <span class="n">Subset.refl</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">⊆</span> <span class="n">s</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">x</span> <span class="n">xs</span> <span class="bp">↦</span> <span class="n">xs</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">Subset.refl</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">xs</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">xs</span> <span class="kd">theorem</span> <span class="n">Subset.trans</span> <span class="o">:</span> <span class="n">r</span> <span class="bp">⊆</span> <span class="n">s</span> <span class="bp">→</span> <span class="n">s</span> <span class="bp">⊆</span> <span class="n">t</span> <span class="bp">→</span> <span class="n">r</span> <span class="bp">⊆</span> <span class="n">t</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">Subset.trans</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Just as we defined <code class="docutils literal notranslate"><span class="pre">FnUb</span></code> for functions,
-
@@ -454,14 +455,14 @@ has an order associated with it.In the next example, we ask you to prove that if <code class="docutils literal notranslate"><span class="pre">a</span></code> is a bound on <code class="docutils literal notranslate"><span class="pre">s</span></code> and <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">≤</span> <span class="pre">b</span></code>, then <code class="docutils literal notranslate"><span class="pre">b</span></code> is a bound on <code class="docutils literal notranslate"><span class="pre">s</span></code> as well.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">PartialOrder</span> <span class="n">α</span><span class="o">]</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">α</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">α</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">PartialOrder</span><span class="w"> </span><span class="n">α</span><span class="o">]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span> <span class="kd">def</span> <span class="n">SetUb</span> <span class="o">(</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">α</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">α</span><span class="o">)</span> <span class="o">:=</span> <span class="bp">∀</span> <span class="n">x</span><span class="o">,</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">s</span> <span class="bp">→</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">a</span> <span class="kd">def</span><span class="w"> </span><span class="n">SetUb</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">SetUb</span> <span class="n">s</span> <span class="n">a</span><span class="o">)</span> <span class="o">(</span><span class="n">h'</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span><span class="o">)</span> <span class="o">:</span> <span class="n">SetUb</span> <span class="n">s</span> <span class="n">b</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">SetUb</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">SetUb</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p id="index-5">We close this section with one last important example.
-
@@ -476,22 +477,22 @@ We then ask you to show that multiplication by a nonzeroconstant is also injective, using the lemma name in the example as a source of inspiration. Recall you should use Ctrl-space completion after guessing the beginning of a lemma name.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">Function</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">Function</span> <span class="kd">example</span> <span class="o">(</span><span class="n">c</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">Injective</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">c</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">x₁</span> <span class="n">x₂</span> <span class="n">h'</span> <span class="n">exact</span> <span class="o">(</span><span class="n">add_left_inj</span> <span class="n">c</span><span class="o">)</span><span class="bp">.</span><span class="n">mp</span> <span class="n">h'</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x₁</span><span class="w"> </span><span class="n">x₂</span><span class="w"> </span><span class="n">h'</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">(</span><span class="n">add_left_inj</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="bp">.</span><span class="n">mp</span><span class="w"> </span><span class="n">h'</span> <span class="kd">example</span> <span class="o">{</span><span class="n">c</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">c</span> <span class="bp">≠</span> <span class="mi">0</span><span class="o">)</span> <span class="o">:</span> <span class="n">Injective</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">c</span> <span class="bp">*</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Finally, show that the composition of two injective functions is injective:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">{</span><span class="n">β</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">{</span><span class="n">γ</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">g</span> <span class="o">:</span> <span class="n">β</span> <span class="bp">→</span> <span class="n">γ</span><span class="o">}</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">β</span><span class="o">}</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">β</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">γ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">γ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">β</span><span class="o">}</span> <span class="kd">example</span> <span class="o">(</span><span class="n">injg</span> <span class="o">:</span> <span class="n">Injective</span> <span class="n">g</span><span class="o">)</span> <span class="o">(</span><span class="n">injf</span> <span class="o">:</span> <span class="n">Injective</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="n">Injective</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">g</span> <span class="o">(</span><span class="n">f</span> <span class="n">x</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">injg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">injf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> </section>
-
@@ -512,29 +513,29 @@ <p id="index-6">There are a few ways we can put the information together.Given a goal that begins with an existential quantifier, the <code class="docutils literal notranslate"><span class="pre">use</span></code> tactic is used to provide the object, leaving the goal of proving the property.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">,</span> <span class="mi">2</span> <span class="bp"><</span> <span class="n">x</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp"><</span> <span class="mi">3</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">use</span> <span class="mi">5</span> <span class="bp">/</span> <span class="mi">2</span> <span class="n">norm_num</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span> <span class="w"> </span><span class="n">norm_num</span> </pre></div> </div> <p>You can give the <code class="docutils literal notranslate"><span class="pre">use</span></code> tactic proofs as well as data:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">,</span> <span class="mi">2</span> <span class="bp"><</span> <span class="n">x</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp"><</span> <span class="mi">3</span> <span class="o">:=</span> <span class="kd">by</span> <span class="k">have</span> <span class="n">h1</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp"><</span> <span class="o">(</span><span class="mi">5</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="bp">/</span> <span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">norm_num</span> <span class="k">have</span> <span class="n">h2</span> <span class="o">:</span> <span class="o">(</span><span class="mi">5</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="bp">/</span> <span class="mi">2</span> <span class="bp"><</span> <span class="mi">3</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">norm_num</span> <span class="n">use</span> <span class="mi">5</span> <span class="bp">/</span> <span class="mi">2</span><span class="o">,</span> <span class="n">h1</span><span class="o">,</span> <span class="n">h2</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="o">(</span><span class="mi">5</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h2</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="mi">5</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="o">,</span><span class="w"> </span><span class="n">h1</span><span class="o">,</span><span class="w"> </span><span class="n">h2</span> </pre></div> </div> <p>In fact, the <code class="docutils literal notranslate"><span class="pre">use</span></code> tactic automatically tries to use available assumptions as well.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">,</span> <span class="mi">2</span> <span class="bp"><</span> <span class="n">x</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp"><</span> <span class="mi">3</span> <span class="o">:=</span> <span class="kd">by</span> <span class="k">have</span> <span class="n">h</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp"><</span> <span class="o">(</span><span class="mi">5</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="bp">/</span> <span class="mi">2</span> <span class="bp">∧</span> <span class="o">(</span><span class="mi">5</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="bp">/</span> <span class="mi">2</span> <span class="bp"><</span> <span class="mi">3</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">norm_num</span> <span class="n">use</span> <span class="mi">5</span> <span class="bp">/</span> <span class="mi">2</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="o">(</span><span class="mi">5</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="o">(</span><span class="mi">5</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span> </pre></div> </div> <p id="index-7">Alternatively, we can use Lean’s <em>anonymous constructor</em> notation to construct a proof of an existential quantifier.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">,</span> <span class="mi">2</span> <span class="bp"><</span> <span class="n">x</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp"><</span> <span class="mi">3</span> <span class="o">:=</span> <span class="k">have</span> <span class="n">h</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp"><</span> <span class="o">(</span><span class="mi">5</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="bp">/</span> <span class="mi">2</span> <span class="bp">∧</span> <span class="o">(</span><span class="mi">5</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="bp">/</span> <span class="mi">2</span> <span class="bp"><</span> <span class="mi">3</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">norm_num</span> <span class="o">⟨</span><span class="mi">5</span> <span class="bp">/</span> <span class="mi">2</span><span class="o">,</span> <span class="n">h</span><span class="o">⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="o">(</span><span class="mi">5</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="o">(</span><span class="mi">5</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span> <span class="w"> </span><span class="o">⟨</span><span class="mi">5</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="o">,</span><span class="w"> </span><span class="n">h</span><span class="o">⟩</span> </pre></div> </div> <p>Notice that there is no <code class="docutils literal notranslate"><span class="pre">by</span></code>; here we are giving an explicit proof term.
-
@@ -544,8 +545,8 @@ tell Lean to put together the given data usingwhatever construction is appropriate for the current goal. We can use the notation without going first into tactic mode:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">,</span> <span class="mi">2</span> <span class="bp"><</span> <span class="n">x</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp"><</span> <span class="mi">3</span> <span class="o">:=</span> <span class="o">⟨</span><span class="mi">5</span> <span class="bp">/</span> <span class="mi">2</span><span class="o">,</span> <span class="kd">by</span> <span class="n">norm_num</span><span class="o">⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">⟨</span><span class="mi">5</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="o">,</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span><span class="o">⟩</span> </pre></div> </div> <p>So now we know how to <em>prove</em> an exists statement.
-
@@ -559,29 +560,29 @@ which say that <code class="docutils literal notranslate"><span class="pre">a</span></code> is an upper bound or lower bound on <code class="docutils literal notranslate"><span class="pre">f</span></code>,respectively. We can use the existential quantifier to say that “<code class="docutils literal notranslate"><span class="pre">f</span></code> is bounded” without specifying the bound:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">FnUb</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="kt">Prop</span> <span class="o">:=</span> <span class="bp">∀</span> <span class="n">x</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">a</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">FnUb</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span> <span class="kd">def</span> <span class="n">FnLb</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="kt">Prop</span> <span class="o">:=</span> <span class="bp">∀</span> <span class="n">x</span><span class="o">,</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">f</span> <span class="n">x</span> <span class="kd">def</span><span class="w"> </span><span class="n">FnLb</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span> <span class="kd">def</span> <span class="n">FnHasUb</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:=</span> <span class="bp">∃</span> <span class="n">a</span><span class="o">,</span> <span class="n">FnUb</span> <span class="n">f</span> <span class="n">a</span> <span class="kd">def</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">FnUb</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span> <span class="kd">def</span> <span class="n">FnHasLb</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:=</span> <span class="bp">∃</span> <span class="n">a</span><span class="o">,</span> <span class="n">FnLb</span> <span class="n">f</span> <span class="n">a</span> <span class="kd">def</span><span class="w"> </span><span class="n">FnHasLb</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">FnLb</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span> </pre></div> </div> <p>We can use the theorem <code class="docutils literal notranslate"><span class="pre">FnUb_add</span></code> from the last section to prove that if <code class="docutils literal notranslate"><span class="pre">f</span></code> and <code class="docutils literal notranslate"><span class="pre">g</span></code> have upper bounds, then so does <code class="docutils literal notranslate"><span class="pre">fun</span> <span class="pre">x</span> <span class="pre">↦</span> <span class="pre">f</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">g</span> <span class="pre">x</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">f</span> <span class="n">g</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">}</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span> <span class="kd">example</span> <span class="o">(</span><span class="n">ubf</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="n">f</span><span class="o">)</span> <span class="o">(</span><span class="n">ubg</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="n">g</span><span class="o">)</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">g</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rcases</span> <span class="n">ubf</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">a</span><span class="o">,</span> <span class="n">ubfa</span><span class="o">⟩</span> <span class="n">rcases</span> <span class="n">ubg</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">b</span><span class="o">,</span> <span class="n">ubgb</span><span class="o">⟩</span> <span class="n">use</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">b</span> <span class="n">apply</span> <span class="n">fnUb_add</span> <span class="n">ubfa</span> <span class="n">ubgb</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">ubf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ubg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">ubf</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">ubfa</span><span class="o">⟩</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">ubg</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">fnUb_add</span><span class="w"> </span><span class="n">ubfa</span><span class="w"> </span><span class="n">ubgb</span> </pre></div> </div> <p id="index-8">The <code class="docutils literal notranslate"><span class="pre">rcases</span></code> tactic unpacks the information
-
@@ -609,35 +610,35 @@ from the last section into named theorems,as we did with <code class="docutils literal notranslate"><span class="pre">fn_ub_add</span></code>, or you can insert the arguments directly into the proofs.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">lbf</span> <span class="o">:</span> <span class="n">FnHasLb</span> <span class="n">f</span><span class="o">)</span> <span class="o">(</span><span class="n">lbg</span> <span class="o">:</span> <span class="n">FnHasLb</span> <span class="n">g</span><span class="o">)</span> <span class="o">:</span> <span class="n">FnHasLb</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">g</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">lbf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasLb</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">lbg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasLb</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasLb</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">{</span><span class="n">c</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">ubf</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="n">f</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">c</span> <span class="bp">≥</span> <span class="mi">0</span><span class="o">)</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">c</span> <span class="bp">*</span> <span class="n">f</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">ubf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p id="index-9">The “r” in <code class="docutils literal notranslate"><span class="pre">rcases</span></code> stands for “recursive,” because it allows us to use arbitrarily complex patterns to unpack nested data. The <code class="docutils literal notranslate"><span class="pre">rintro</span></code> tactic is a combination of <code class="docutils literal notranslate"><span class="pre">intro</span></code> and <code class="docutils literal notranslate"><span class="pre">rcases</span></code>:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="n">f</span> <span class="bp">→</span> <span class="n">FnHasUb</span> <span class="n">g</span> <span class="bp">→</span> <span class="n">FnHasUb</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">g</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rintro</span> <span class="o">⟨</span><span class="n">a</span><span class="o">,</span> <span class="n">ubfa</span><span class="o">⟩</span> <span class="o">⟨</span><span class="n">b</span><span class="o">,</span> <span class="n">ubgb</span><span class="o">⟩</span> <span class="n">exact</span> <span class="o">⟨</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">,</span> <span class="n">fnUb_add</span> <span class="n">ubfa</span> <span class="n">ubgb</span><span class="o">⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">ubfa</span><span class="o">⟩</span><span class="w"> </span><span class="o">⟨</span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">fnUb_add</span><span class="w"> </span><span class="n">ubfa</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span> </pre></div> </div> <p>In fact, Lean also supports a pattern-matching fun in expressions and proof terms:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="n">f</span> <span class="bp">→</span> <span class="n">FnHasUb</span> <span class="n">g</span> <span class="bp">→</span> <span class="n">FnHasUb</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">g</span> <span class="n">x</span> <span class="o">:=</span> <span class="k">fun</span> <span class="o">⟨</span><span class="n">a</span><span class="o">,</span> <span class="n">ubfa</span><span class="o">⟩</span> <span class="o">⟨</span><span class="n">b</span><span class="o">,</span> <span class="n">ubgb</span><span class="o">⟩</span> <span class="bp">↦</span> <span class="o">⟨</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">,</span> <span class="n">fnUb_add</span> <span class="n">ubfa</span> <span class="n">ubgb</span><span class="o">⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">ubfa</span><span class="o">⟩</span><span class="w"> </span><span class="o">⟨</span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">fnUb_add</span><span class="w"> </span><span class="n">ubfa</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span> </pre></div> </div> <p>The task of unpacking information in a hypothesis is so important that Lean and Mathlib provide a number of ways to do it. For example, the <code class="docutils literal notranslate"><span class="pre">obtain</span></code> tactic provides suggestive syntax:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">ubf</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="n">f</span><span class="o">)</span> <span class="o">(</span><span class="n">ubg</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="n">g</span><span class="o">)</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">g</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">obtain</span> <span class="o">⟨</span><span class="n">a</span><span class="o">,</span> <span class="n">ubfa</span><span class="o">⟩</span> <span class="o">:=</span> <span class="n">ubf</span> <span class="n">obtain</span> <span class="o">⟨</span><span class="n">b</span><span class="o">,</span> <span class="n">ubgb</span><span class="o">⟩</span> <span class="o">:=</span> <span class="n">ubg</span> <span class="n">exact</span> <span class="o">⟨</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">,</span> <span class="n">fnUb_add</span> <span class="n">ubfa</span> <span class="n">ubgb</span><span class="o">⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">ubf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ubg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">obtain</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">ubfa</span><span class="o">⟩</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">ubf</span> <span class="w"> </span><span class="n">obtain</span><span class="w"> </span><span class="o">⟨</span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">ubg</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">fnUb_add</span><span class="w"> </span><span class="n">ubfa</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span> </pre></div> </div> <p>Think of the first <code class="docutils literal notranslate"><span class="pre">obtain</span></code> instruction as matching the “contents” of <code class="docutils literal notranslate"><span class="pre">ubf</span></code>
-
@@ -647,29 +648,29 @@ there is a small difference in that <code class="docutils literal notranslate"><span class="pre">rcases</span></code> clears <code class="docutils literal notranslate"><span class="pre">ubf</span></code> from the contextwhen it is done, whereas it is still present after <code class="docutils literal notranslate"><span class="pre">obtain</span></code>.</p> <p>Lean also supports syntax that is similar to that used in other functional programming languages:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">ubf</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="n">f</span><span class="o">)</span> <span class="o">(</span><span class="n">ubg</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="n">g</span><span class="o">)</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">g</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">cases</span> <span class="n">ubf</span> <span class="n">case</span> <span class="n">intro</span> <span class="n">a</span> <span class="n">ubfa</span> <span class="bp">=></span> <span class="n">cases</span> <span class="n">ubg</span> <span class="n">case</span> <span class="n">intro</span> <span class="n">b</span> <span class="n">ubgb</span> <span class="bp">=></span> <span class="n">exact</span> <span class="o">⟨</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">,</span> <span class="n">fnUb_add</span> <span class="n">ubfa</span> <span class="n">ubgb</span><span class="o">⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">ubf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ubg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">cases</span><span class="w"> </span><span class="n">ubf</span> <span class="w"> </span><span class="n">case</span><span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">ubfa</span><span class="w"> </span><span class="bp">=></span> <span class="w"> </span><span class="n">cases</span><span class="w"> </span><span class="n">ubg</span> <span class="w"> </span><span class="n">case</span><span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">ubgb</span><span class="w"> </span><span class="bp">=></span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">fnUb_add</span><span class="w"> </span><span class="n">ubfa</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span> <span class="kd">example</span> <span class="o">(</span><span class="n">ubf</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="n">f</span><span class="o">)</span> <span class="o">(</span><span class="n">ubg</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="n">g</span><span class="o">)</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">g</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">cases</span> <span class="n">ubf</span> <span class="n">next</span> <span class="n">a</span> <span class="n">ubfa</span> <span class="bp">=></span> <span class="n">cases</span> <span class="n">ubg</span> <span class="n">next</span> <span class="n">b</span> <span class="n">ubgb</span> <span class="bp">=></span> <span class="n">exact</span> <span class="o">⟨</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">,</span> <span class="n">fnUb_add</span> <span class="n">ubfa</span> <span class="n">ubgb</span><span class="o">⟩</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">ubf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ubg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">cases</span><span class="w"> </span><span class="n">ubf</span> <span class="w"> </span><span class="n">next</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">ubfa</span><span class="w"> </span><span class="bp">=></span> <span class="w"> </span><span class="n">cases</span><span class="w"> </span><span class="n">ubg</span> <span class="w"> </span><span class="n">next</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">ubgb</span><span class="w"> </span><span class="bp">=></span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">fnUb_add</span><span class="w"> </span><span class="n">ubfa</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span> <span class="kd">example</span> <span class="o">(</span><span class="n">ubf</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="n">f</span><span class="o">)</span> <span class="o">(</span><span class="n">ubg</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="n">g</span><span class="o">)</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">g</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="k">match</span> <span class="n">ubf</span><span class="o">,</span> <span class="n">ubg</span> <span class="k">with</span> <span class="bp">|</span> <span class="o">⟨</span><span class="n">a</span><span class="o">,</span> <span class="n">ubfa</span><span class="o">⟩,</span> <span class="o">⟨</span><span class="n">b</span><span class="o">,</span> <span class="n">ubgb</span><span class="o">⟩</span> <span class="bp">=></span> <span class="n">exact</span> <span class="o">⟨</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">,</span> <span class="n">fnUb_add</span> <span class="n">ubfa</span> <span class="n">ubgb</span><span class="o">⟩</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">ubf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ubg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">ubf</span><span class="o">,</span><span class="w"> </span><span class="n">ubg</span><span class="w"> </span><span class="k">with</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">ubfa</span><span class="o">⟩,</span><span class="w"> </span><span class="o">⟨</span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span><span class="w"> </span><span class="bp">=></span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">fnUb_add</span><span class="w"> </span><span class="n">ubfa</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span> <span class="kd">example</span> <span class="o">(</span><span class="n">ubf</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="n">f</span><span class="o">)</span> <span class="o">(</span><span class="n">ubg</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="n">g</span><span class="o">)</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">g</span> <span class="n">x</span> <span class="o">:=</span> <span class="k">match</span> <span class="n">ubf</span><span class="o">,</span> <span class="n">ubg</span> <span class="k">with</span> <span class="bp">|</span> <span class="o">⟨</span><span class="n">a</span><span class="o">,</span> <span class="n">ubfa</span><span class="o">⟩,</span> <span class="o">⟨</span><span class="n">b</span><span class="o">,</span> <span class="n">ubgb</span><span class="o">⟩</span> <span class="bp">=></span> <span class="o">⟨</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">,</span> <span class="n">fnUb_add</span> <span class="n">ubfa</span> <span class="n">ubgb</span><span class="o">⟩</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">ubf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ubg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">ubf</span><span class="o">,</span><span class="w"> </span><span class="n">ubg</span><span class="w"> </span><span class="k">with</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">ubfa</span><span class="o">⟩,</span><span class="w"> </span><span class="o">⟨</span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span><span class="w"> </span><span class="bp">=></span> <span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">fnUb_add</span><span class="w"> </span><span class="n">ubfa</span><span class="w"> </span><span class="n">ubgb</span><span class="o">⟩</span> </pre></div> </div> <p>In the first example, if you put your cursor after <code class="docutils literal notranslate"><span class="pre">cases</span> <span class="pre">ubf</span></code>,
-
@@ -699,18 +700,18 @@ quantifiers at once.We then provide the magic values needed to express <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">*</span> <span class="pre">y</span></code> as a sum of squares as a list to the <code class="docutils literal notranslate"><span class="pre">use</span></code> statement, and we use <code class="docutils literal notranslate"><span class="pre">ring</span></code> to verify that they work.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">α</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">α</span><span class="o">]</span> <span class="kd">def</span> <span class="n">SumOfSquares</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">α</span><span class="o">)</span> <span class="o">:=</span> <span class="bp">∃</span> <span class="n">a</span> <span class="n">b</span><span class="o">,</span> <span class="n">x</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">^</span> <span class="mi">2</span> <span class="kd">def</span><span class="w"> </span><span class="n">SumOfSquares</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span> <span class="kd">theorem</span> <span class="n">sumOfSquares_mul</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">α</span><span class="o">}</span> <span class="o">(</span><span class="n">sosx</span> <span class="o">:</span> <span class="n">SumOfSquares</span> <span class="n">x</span><span class="o">)</span> <span class="o">(</span><span class="n">sosy</span> <span class="o">:</span> <span class="n">SumOfSquares</span> <span class="n">y</span><span class="o">)</span> <span class="o">:</span> <span class="n">SumOfSquares</span> <span class="o">(</span><span class="n">x</span> <span class="bp">*</span> <span class="n">y</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rcases</span> <span class="n">sosx</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">a</span><span class="o">,</span> <span class="n">b</span><span class="o">,</span> <span class="n">xeq</span><span class="o">⟩</span> <span class="n">rcases</span> <span class="n">sosy</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">c</span><span class="o">,</span> <span class="n">d</span><span class="o">,</span> <span class="n">yeq</span><span class="o">⟩</span> <span class="n">rw</span> <span class="o">[</span><span class="n">xeq</span><span class="o">,</span> <span class="n">yeq</span><span class="o">]</span> <span class="n">use</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">c</span> <span class="bp">-</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">d</span><span class="o">,</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">d</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">c</span> <span class="n">ring</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">sumOfSquares_mul</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">sosx</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">SumOfSquares</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">sosy</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">SumOfSquares</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">SumOfSquares</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">sosx</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">xeq</span><span class="o">⟩</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">sosy</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">c</span><span class="o">,</span><span class="w"> </span><span class="n">d</span><span class="o">,</span><span class="w"> </span><span class="n">yeq</span><span class="o">⟩</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">xeq</span><span class="o">,</span><span class="w"> </span><span class="n">yeq</span><span class="o">]</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">d</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span> <span class="w"> </span><span class="n">ring</span> </pre></div> </div> <p>This proof doesn’t provide much insight,
-
@@ -740,23 +741,23 @@ an abbreviation:if you use the keyword <code class="docutils literal notranslate"><span class="pre">rfl</span></code> in place of a new identifier, <code class="docutils literal notranslate"><span class="pre">rcases</span></code> does the rewriting automatically (this trick doesn’t work with pattern-matching lambdas).</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">sumOfSquares_mul'</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">α</span><span class="o">}</span> <span class="o">(</span><span class="n">sosx</span> <span class="o">:</span> <span class="n">SumOfSquares</span> <span class="n">x</span><span class="o">)</span> <span class="o">(</span><span class="n">sosy</span> <span class="o">:</span> <span class="n">SumOfSquares</span> <span class="n">y</span><span class="o">)</span> <span class="o">:</span> <span class="n">SumOfSquares</span> <span class="o">(</span><span class="n">x</span> <span class="bp">*</span> <span class="n">y</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rcases</span> <span class="n">sosx</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">a</span><span class="o">,</span> <span class="n">b</span><span class="o">,</span> <span class="n">rfl</span><span class="o">⟩</span> <span class="n">rcases</span> <span class="n">sosy</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">c</span><span class="o">,</span> <span class="n">d</span><span class="o">,</span> <span class="n">rfl</span><span class="o">⟩</span> <span class="n">use</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">c</span> <span class="bp">-</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">d</span><span class="o">,</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">d</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">c</span> <span class="n">ring</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">sumOfSquares_mul'</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">sosx</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">SumOfSquares</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">sosy</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">SumOfSquares</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">SumOfSquares</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">sosx</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">rfl</span><span class="o">⟩</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">sosy</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">c</span><span class="o">,</span><span class="w"> </span><span class="n">d</span><span class="o">,</span><span class="w"> </span><span class="n">rfl</span><span class="o">⟩</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">d</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span> <span class="w"> </span><span class="n">ring</span> </pre></div> </div> <p>As with the universal quantifier, you can find existential quantifiers hidden all over if you know how to spot them. For example, divisibility is implicitly an “exists” statement.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">divab</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">∣</span> <span class="n">b</span><span class="o">)</span> <span class="o">(</span><span class="n">divbc</span> <span class="o">:</span> <span class="n">b</span> <span class="bp">∣</span> <span class="n">c</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">∣</span> <span class="n">c</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rcases</span> <span class="n">divab</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">d</span><span class="o">,</span> <span class="n">beq</span><span class="o">⟩</span> <span class="n">rcases</span> <span class="n">divbc</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">e</span><span class="o">,</span> <span class="n">ceq</span><span class="o">⟩</span> <span class="n">rw</span> <span class="o">[</span><span class="n">ceq</span><span class="o">,</span> <span class="n">beq</span><span class="o">]</span> <span class="n">use</span> <span class="n">d</span> <span class="bp">*</span> <span class="n">e</span><span class="bp">;</span> <span class="n">ring</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">divab</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">divbc</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">divab</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">d</span><span class="o">,</span><span class="w"> </span><span class="n">beq</span><span class="o">⟩</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">divbc</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">e</span><span class="o">,</span><span class="w"> </span><span class="n">ceq</span><span class="o">⟩</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">ceq</span><span class="o">,</span><span class="w"> </span><span class="n">beq</span><span class="o">]</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">e</span><span class="bp">;</span><span class="w"> </span><span class="n">ring</span> </pre></div> </div> <p>And once again, this provides a nice setting for using
-
@@ -764,8 +765,8 @@ <code class="docutils literal notranslate"><span class="pre">rcases</span></code> with <code class="docutils literal notranslate"><span class="pre">rfl</span></code>.Try it out in the proof above. It feels pretty good!</p> <p>Then try proving the following:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">divab</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">∣</span> <span class="n">b</span><span class="o">)</span> <span class="o">(</span><span class="n">divac</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">∣</span> <span class="n">c</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">∣</span> <span class="n">b</span> <span class="bp">+</span> <span class="n">c</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">divab</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">divac</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p id="index-10">For another important example, a function <span class="math notranslate nohighlight">\(f : \alpha \to \beta\)</span>
-
@@ -776,43 +777,43 @@ such that <span class="math notranslate nohighlight">\(f(x) = y\)</span>.Notice that this statement includes both a universal and an existential quantifier, which explains why the next example makes use of both <code class="docutils literal notranslate"><span class="pre">intro</span></code> and <code class="docutils literal notranslate"><span class="pre">use</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">c</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">:</span> <span class="n">Surjective</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">c</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">x</span> <span class="n">use</span> <span class="n">x</span> <span class="bp">-</span> <span class="n">c</span> <span class="n">dsimp</span><span class="bp">;</span> <span class="n">ring</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Surjective</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">c</span> <span class="w"> </span><span class="n">dsimp</span><span class="bp">;</span><span class="w"> </span><span class="n">ring</span> </pre></div> </div> <p>Try this example yourself using the theorem <code class="docutils literal notranslate"><span class="pre">mul_div_cancel₀</span></code>.:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">c</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">c</span> <span class="bp">≠</span> <span class="mi">0</span><span class="o">)</span> <span class="o">:</span> <span class="n">Surjective</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">c</span> <span class="bp">*</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Surjective</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p id="index-11">At this point, it is worth mentioning that there is a tactic, <code class="docutils literal notranslate"><span class="pre">field_simp</span></code>, that will often clear denominators in a useful way. It can be used in conjunction with the <code class="docutils literal notranslate"><span class="pre">ring</span></code> tactic.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">-</span> <span class="n">y</span> <span class="bp">≠</span> <span class="mi">0</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">x</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">-</span> <span class="n">y</span> <span class="bp">^</span> <span class="mi">2</span><span class="o">)</span> <span class="bp">/</span> <span class="o">(</span><span class="n">x</span> <span class="bp">-</span> <span class="n">y</span><span class="o">)</span> <span class="bp">=</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">field_simp</span> <span class="o">[</span><span class="n">h</span><span class="o">]</span> <span class="n">ring</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">field_simp</span><span class="w"> </span><span class="o">[</span><span class="n">h</span><span class="o">]</span> <span class="w"> </span><span class="n">ring</span> </pre></div> </div> <p>The next example uses a surjectivity hypothesis by applying it to a suitable value. Note that you can use <code class="docutils literal notranslate"><span class="pre">rcases</span></code> with any expression, not just a hypothesis.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">Surjective</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">=</span> <span class="mi">4</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rcases</span> <span class="n">h</span> <span class="mi">2</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">x</span><span class="o">,</span> <span class="n">hx</span><span class="o">⟩</span> <span class="n">use</span> <span class="n">x</span> <span class="n">rw</span> <span class="o">[</span><span class="n">hx</span><span class="o">]</span> <span class="n">norm_num</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Surjective</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">hx</span><span class="o">⟩</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">hx</span><span class="o">]</span> <span class="w"> </span><span class="n">norm_num</span> </pre></div> </div> <p>See if you can use these methods to show that the composition of surjective functions is surjective.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">{</span><span class="n">β</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">{</span><span class="n">γ</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">g</span> <span class="o">:</span> <span class="n">β</span> <span class="bp">→</span> <span class="n">γ</span><span class="o">}</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">β</span><span class="o">}</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">β</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">γ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">γ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">β</span><span class="o">}</span> <span class="kd">example</span> <span class="o">(</span><span class="n">surjg</span> <span class="o">:</span> <span class="n">Surjective</span> <span class="n">g</span><span class="o">)</span> <span class="o">(</span><span class="n">surjf</span> <span class="o">:</span> <span class="n">Surjective</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="n">Surjective</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">g</span> <span class="o">(</span><span class="n">f</span> <span class="n">x</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">surjg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Surjective</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">surjf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Surjective</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Surjective</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> </section>
-
@@ -838,10 +839,10 @@ which says that we have <code class="docutils literal notranslate"><span class="pre">¬</span> <span class="pre">a</span> <span class="pre"><</span> <span class="pre">a</span></code> for every <code class="docutils literal notranslate"><span class="pre">a</span></code>.The asymmetry principle <code class="docutils literal notranslate"><span class="pre">lt_asymm</span></code> says that we have <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre"><</span> <span class="pre">b</span> <span class="pre">→</span> <span class="pre">¬</span> <span class="pre">b</span> <span class="pre"><</span> <span class="pre">a</span></code>. Let’s show that <code class="docutils literal notranslate"><span class="pre">lt_asymm</span></code> follows from <code class="docutils literal notranslate"><span class="pre">lt_irrefl</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">b</span><span class="o">)</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">b</span> <span class="bp"><</span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">h'</span> <span class="k">have</span> <span class="o">:</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">a</span> <span class="o">:=</span> <span class="n">lt_trans</span> <span class="n">h</span> <span class="n">h'</span> <span class="n">apply</span> <span class="n">lt_irrefl</span> <span class="n">a</span> <span class="n">this</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">b</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h'</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">lt_trans</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="n">h'</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">lt_irrefl</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">this</span> </pre></div> </div> <p id="index-12">This example introduces a couple of new tricks.
-
@@ -858,41 +859,41 @@ by applying <code class="docutils literal notranslate"><span class="pre">lt_irrefl</span></code> to a proof of <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre"><</span> <span class="pre">a</span></code>.</p><p>Here is another example, which uses the predicate <code class="docutils literal notranslate"><span class="pre">FnHasUb</span></code> defined in the last section, which says that a function has an upper bound.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">x</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">></span> <span class="n">a</span><span class="o">)</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">FnHasUb</span> <span class="n">f</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">fnub</span> <span class="n">rcases</span> <span class="n">fnub</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">a</span><span class="o">,</span> <span class="n">fnuba</span><span class="o">⟩</span> <span class="n">rcases</span> <span class="n">h</span> <span class="n">a</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">x</span><span class="o">,</span> <span class="n">hx</span><span class="o">⟩</span> <span class="k">have</span> <span class="o">:</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">a</span> <span class="o">:=</span> <span class="n">fnuba</span> <span class="n">x</span> <span class="n">linarith</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">fnub</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">fnub</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">fnuba</span><span class="o">⟩</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">hx</span><span class="o">⟩</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">fnuba</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="n">linarith</span> </pre></div> </div> <p>Remember that it is often convenient to use <code class="docutils literal notranslate"><span class="pre">linarith</span></code> when a goal follows from linear equations and inequalities that are in the context.</p> <p>See if you can prove these in a similar way:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">x</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="bp"><</span> <span class="n">a</span><span class="o">)</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">FnHasLb</span> <span class="n">f</span> <span class="o">:=</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">FnHasLb</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">FnHasUb</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">x</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">FnHasUb</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Mathlib offers a number of useful theorems for relating orders and negations:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="o">(</span><span class="n">not_le_of_gt</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">></span> <span class="n">b</span> <span class="bp">→</span> <span class="bp">¬</span><span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">not_lt_of_ge</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≥</span> <span class="n">b</span> <span class="bp">→</span> <span class="bp">¬</span><span class="n">a</span> <span class="bp"><</span> <span class="n">b</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">lt_of_not_ge</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">a</span> <span class="bp">≥</span> <span class="n">b</span> <span class="bp">→</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">b</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">le_of_not_gt</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">a</span> <span class="bp">></span> <span class="n">b</span> <span class="bp">→</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">not_le_of_gt</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">¬</span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">not_lt_of_ge</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">¬</span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">lt_of_not_ge</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">a</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">le_of_not_gt</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">a</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> </pre></div> </div> <p>Recall the predicate <code class="docutils literal notranslate"><span class="pre">Monotone</span> <span class="pre">f</span></code>, which says that <code class="docutils literal notranslate"><span class="pre">f</span></code> is nondecreasing. Use some of the theorems just enumerated to prove the following:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">Monotone</span> <span class="n">f</span><span class="o">)</span> <span class="o">(</span><span class="n">h'</span> <span class="o">:</span> <span class="n">f</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">f</span> <span class="n">b</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">b</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span><span class="o">)</span> <span class="o">(</span><span class="n">h'</span> <span class="o">:</span> <span class="n">f</span> <span class="n">b</span> <span class="bp"><</span> <span class="n">f</span> <span class="n">a</span><span class="o">)</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">Monotone</span> <span class="n">f</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">Monotone</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>We can show that the first example in the last snippet
-
@@ -900,12 +901,12 @@ cannot be proved if we replace <code class="docutils literal notranslate"><span class="pre"><</span></code> by <code class="docutils literal notranslate"><span class="pre">≤</span></code>.Notice that we can prove the negation of a universally quantified statement by giving a counterexample. Complete the proof.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="bp">¬∀</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">},</span> <span class="n">Monotone</span> <span class="n">f</span> <span class="bp">→</span> <span class="bp">∀</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span><span class="o">},</span> <span class="n">f</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">f</span> <span class="n">b</span> <span class="bp">→</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">h</span> <span class="k">let</span> <span class="n">f</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">↦</span> <span class="o">(</span><span class="mi">0</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="k">have</span> <span class="n">monof</span> <span class="o">:</span> <span class="n">Monotone</span> <span class="n">f</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="n">h'</span> <span class="o">:</span> <span class="n">f</span> <span class="mi">1</span> <span class="bp">≤</span> <span class="n">f</span> <span class="mi">0</span> <span class="o">:=</span> <span class="n">le_refl</span> <span class="n">_</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬∀</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">},</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="o">},</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="k">let</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">(</span><span class="mi">0</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">monof</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">le_refl</span><span class="w"> </span><span class="n">_</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p id="index-13">This example introduces the <code class="docutils literal notranslate"><span class="pre">let</span></code> tactic,
-
@@ -917,8 +918,8 @@ Lean will unfold the definition of <code class="docutils literal notranslate"><span class="pre">f</span></code> when it has to.In particular, when we prove <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">1</span> <span class="pre">≤</span> <span class="pre">f</span> <span class="pre">0</span></code> with <code class="docutils literal notranslate"><span class="pre">le_refl</span></code>, Lean reduces <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">1</span></code> and <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">0</span></code> to <code class="docutils literal notranslate"><span class="pre">0</span></code>.</p> <p>Use <code class="docutils literal notranslate"><span class="pre">le_of_not_gt</span></code> to prove the following:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">ε</span> <span class="bp">></span> <span class="mi">0</span><span class="o">,</span> <span class="n">x</span> <span class="bp"><</span> <span class="n">ε</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Implicit in many of the proofs we have just done
-
@@ -931,19 +932,19 @@ is equivalent to saying that something fails to have property <code class="docutils literal notranslate"><span class="pre">P</span></code>.In other words, all four of the following implications are valid (but one of them cannot be proved with what we explained so far):</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">(</span><span class="n">P</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="kt">Prop</span><span class="o">)</span> <span class="o">(</span><span class="n">Q</span> <span class="o">:</span> <span class="kt">Prop</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">P</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="kt">Prop</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">Q</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="o">)</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">¬∃</span> <span class="n">x</span><span class="o">,</span> <span class="n">P</span> <span class="n">x</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span><span class="o">,</span> <span class="bp">¬</span><span class="n">P</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="bp">¬</span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span><span class="o">,</span> <span class="bp">¬</span><span class="n">P</span> <span class="n">x</span><span class="o">)</span> <span class="o">:</span> <span class="bp">¬∃</span> <span class="n">x</span><span class="o">,</span> <span class="n">P</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="bp">¬</span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">¬∀</span> <span class="n">x</span><span class="o">,</span> <span class="n">P</span> <span class="n">x</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span><span class="o">,</span> <span class="bp">¬</span><span class="n">P</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="bp">¬</span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span><span class="o">,</span> <span class="bp">¬</span><span class="n">P</span> <span class="n">x</span><span class="o">)</span> <span class="o">:</span> <span class="bp">¬∀</span> <span class="n">x</span><span class="o">,</span> <span class="n">P</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="bp">¬</span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>The first, second, and fourth are straightforward to
-
@@ -955,13 +956,13 @@ from the fact that its nonexistence is contradictory.This is an instance of <em>classical</em> mathematical reasoning. We can use proof by contradiction to prove the third implication as follows.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">¬∀</span> <span class="n">x</span><span class="o">,</span> <span class="n">P</span> <span class="n">x</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span><span class="o">,</span> <span class="bp">¬</span><span class="n">P</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">by_contra</span> <span class="n">h'</span> <span class="n">apply</span> <span class="n">h</span> <span class="n">intro</span> <span class="n">x</span> <span class="k">show</span> <span class="n">P</span> <span class="n">x</span> <span class="n">by_contra</span> <span class="n">h''</span> <span class="n">exact</span> <span class="n">h'</span> <span class="o">⟨</span><span class="n">x</span><span class="o">,</span> <span class="n">h''</span><span class="o">⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="bp">¬</span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">by_contra</span><span class="w"> </span><span class="n">h'</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="k">show</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="n">by_contra</span><span class="w"> </span><span class="n">h''</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h'</span><span class="w"> </span><span class="o">⟨</span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">h''</span><span class="o">⟩</span> </pre></div> </div> <p id="index-14">Make sure you understand how this works.
-
@@ -974,18 +975,18 @@ Confirm that you can prove the forward directionof this equivalence using <code class="docutils literal notranslate"><span class="pre">by_contra</span></code>, while the reverse direction follows from the ordinary rules for negation.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">¬¬</span><span class="n">Q</span><span class="o">)</span> <span class="o">:</span> <span class="n">Q</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬¬</span><span class="n">Q</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">Q</span><span class="o">)</span> <span class="o">:</span> <span class="bp">¬¬</span><span class="n">Q</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Q</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬¬</span><span class="n">Q</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Use proof by contradiction to establish the following, which is the converse of one of the implications we proved above. (Hint: use <code class="docutils literal notranslate"><span class="pre">intro</span></code> first.)</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">FnHasUb</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">x</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">></span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p id="index-15">It is often tedious to work with compound statements with
-
@@ -996,14 +997,14 @@ has been pushed inward.To facilitate this, Mathlib offers a <code class="docutils literal notranslate"><span class="pre">push_neg</span></code> tactic, which restates the goal in this way. The command <code class="docutils literal notranslate"><span class="pre">push_neg</span> <span class="pre">at</span> <span class="pre">h</span></code> restates the hypothesis <code class="docutils literal notranslate"><span class="pre">h</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">¬∀</span> <span class="n">a</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">x</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">></span> <span class="n">a</span><span class="o">)</span> <span class="o">:</span> <span class="n">FnHasUb</span> <span class="n">f</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">push_neg</span> <span class="n">at</span> <span class="n">h</span> <span class="n">exact</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬∀</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">push_neg</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">FnHasUb</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">x</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">></span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">dsimp</span> <span class="n">only</span> <span class="o">[</span><span class="n">FnHasUb</span><span class="o">,</span> <span class="n">FnUb</span><span class="o">]</span> <span class="n">at</span> <span class="n">h</span> <span class="n">push_neg</span> <span class="n">at</span> <span class="n">h</span> <span class="n">exact</span> <span class="n">h</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">dsimp</span><span class="w"> </span><span class="n">only</span><span class="w"> </span><span class="o">[</span><span class="n">FnHasUb</span><span class="o">,</span><span class="w"> </span><span class="n">FnUb</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">push_neg</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>In the second example, we use dsimp to
-
@@ -1018,8 +1019,8 @@ Without even knowing how to use the conjunctionsymbol, you should be able to use <code class="docutils literal notranslate"><span class="pre">push_neg</span></code> to prove the following:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">Monotone</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span> <span class="n">y</span><span class="o">,</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">∧</span> <span class="n">f</span> <span class="n">y</span> <span class="bp"><</span> <span class="n">f</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">Monotone</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p id="index-16">Mathlib also has a tactic, <code class="docutils literal notranslate"><span class="pre">contrapose</span></code>,
-
@@ -1031,14 +1032,14 @@ <code class="docutils literal notranslate"><span class="pre">¬A</span></code> from hypothesis <code class="docutils literal notranslate"><span class="pre">¬B</span></code>.Using <code class="docutils literal notranslate"><span class="pre">contrapose!</span></code> instead of <code class="docutils literal notranslate"><span class="pre">contrapose</span></code> applies <code class="docutils literal notranslate"><span class="pre">push_neg</span></code> to the goal and the relevant hypothesis as well.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">FnHasUb</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">x</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">></span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">contrapose</span><span class="bp">!</span> <span class="n">h</span> <span class="n">exact</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">FnHasUb</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span> <span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">ε</span> <span class="bp">></span> <span class="mi">0</span><span class="o">,</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">ε</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">contrapose</span><span class="bp">!</span> <span class="n">h</span> <span class="n">use</span> <span class="n">x</span> <span class="bp">/</span> <span class="mi">2</span> <span class="n">constructor</span> <span class="bp"><;></span> <span class="n">linarith</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">ε</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span> <span class="w"> </span><span class="n">constructor</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">linarith</span> </pre></div> </div> <p>We have not yet explained the <code class="docutils literal notranslate"><span class="pre">constructor</span></code> command
-
@@ -1060,16 +1061,16 @@ (We will see instances of reasoning by cases in<a class="reference internal" href="#disjunction"><span class="std std-numref">Section 3.5</span></a>.)</p> <p id="index-17">Lean provides a number of ways of closing a goal once a contradiction has been reached.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="mi">0</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">></span> <span class="mi">37</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">exfalso</span> <span class="n">apply</span> <span class="n">lt_irrefl</span> <span class="mi">0</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">37</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">exfalso</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">lt_irrefl</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="n">h</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="mi">0</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">></span> <span class="mi">37</span> <span class="o">:=</span> <span class="n">absurd</span> <span class="n">h</span> <span class="o">(</span><span class="n">lt_irrefl</span> <span class="mi">0</span><span class="o">)</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">37</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">absurd</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">(</span><span class="n">lt_irrefl</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="mi">0</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">></span> <span class="mi">37</span> <span class="o">:=</span> <span class="kd">by</span> <span class="k">have</span> <span class="n">h'</span> <span class="o">:</span> <span class="bp">¬</span><span class="mi">0</span> <span class="bp"><</span> <span class="mi">0</span> <span class="o">:=</span> <span class="n">lt_irrefl</span> <span class="mi">0</span> <span class="n">contradiction</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">37</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">lt_irrefl</span><span class="w"> </span><span class="mi">0</span> <span class="w"> </span><span class="n">contradiction</span> </pre></div> </div> <p>The <code class="docutils literal notranslate"><span class="pre">exfalso</span></code> tactic replaces the current goal with
-
@@ -1088,12 +1089,12 @@ is used to express “and.”The <code class="docutils literal notranslate"><span class="pre">constructor</span></code> tactic allows you to prove a statement of the form <code class="docutils literal notranslate"><span class="pre">A</span> <span class="pre">∧</span> <span class="pre">B</span></code> by proving <code class="docutils literal notranslate"><span class="pre">A</span></code> and then proving <code class="docutils literal notranslate"><span class="pre">B</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h₀</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span><span class="o">)</span> <span class="o">(</span><span class="n">h₁</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">y</span> <span class="bp">≤</span> <span class="n">x</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp">≠</span> <span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">constructor</span> <span class="bp">·</span> <span class="n">assumption</span> <span class="n">intro</span> <span class="n">h</span> <span class="n">apply</span> <span class="n">h₁</span> <span class="n">rw</span> <span class="o">[</span><span class="n">h</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">constructor</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">assumption</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">h₁</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">h</span><span class="o">]</span> </pre></div> </div> <p id="index-19">In this example, the <code class="docutils literal notranslate"><span class="pre">assumption</span></code> tactic
-
@@ -1106,14 +1107,14 @@ angle brackets.The first is a slick proof-term version of the previous proof, which drops into tactic mode at the keyword <code class="docutils literal notranslate"><span class="pre">by</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h₀</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span><span class="o">)</span> <span class="o">(</span><span class="n">h₁</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">y</span> <span class="bp">≤</span> <span class="n">x</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp">≠</span> <span class="n">y</span> <span class="o">:=</span> <span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span> <span class="k">fun</span> <span class="n">h</span> <span class="bp">↦</span> <span class="n">h₁</span> <span class="o">(</span><span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">h</span><span class="o">])⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="o">(</span><span class="kd">by</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">h</span><span class="o">])⟩</span> <span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h₀</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span><span class="o">)</span> <span class="o">(</span><span class="n">h₁</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">y</span> <span class="bp">≤</span> <span class="n">x</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp">≠</span> <span class="n">y</span> <span class="o">:=</span> <span class="k">have</span> <span class="n">h</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≠</span> <span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">contrapose</span><span class="bp">!</span> <span class="n">h₁</span> <span class="n">rw</span> <span class="o">[</span><span class="n">h₁</span><span class="o">]</span> <span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span> <span class="n">h</span><span class="o">⟩</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span><span class="w"> </span><span class="n">h₁</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">h₁</span><span class="o">]</span> <span class="w"> </span><span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span><span class="w"> </span><span class="n">h</span><span class="o">⟩</span> </pre></div> </div> <p><em>Using</em> a conjunction instead of proving one involves unpacking the proofs of the
-
@@ -1122,46 +1123,46 @@ You can use the <code class="docutils literal notranslate"><span class="pre">rcases</span></code> tactic for that,as well as <code class="docutils literal notranslate"><span class="pre">rintro</span></code> or a pattern-matching <code class="docutils literal notranslate"><span class="pre">fun</span></code>, all in a manner similar to the way they are used with the existential quantifier.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp">≠</span> <span class="n">y</span><span class="o">)</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">y</span> <span class="bp">≤</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rcases</span> <span class="n">h</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span> <span class="n">h₁</span><span class="o">⟩</span> <span class="n">contrapose</span><span class="bp">!</span> <span class="n">h₁</span> <span class="n">exact</span> <span class="n">le_antisymm</span> <span class="n">h₀</span> <span class="n">h₁</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span><span class="w"> </span><span class="n">h₁</span><span class="o">⟩</span> <span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span><span class="w"> </span><span class="n">h₁</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span> <span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp">≠</span> <span class="n">y</span> <span class="bp">→</span> <span class="bp">¬</span><span class="n">y</span> <span class="bp">≤</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rintro</span> <span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span> <span class="n">h₁</span><span class="o">⟩</span> <span class="n">h'</span> <span class="n">exact</span> <span class="n">h₁</span> <span class="o">(</span><span class="n">le_antisymm</span> <span class="n">h₀</span> <span class="n">h'</span><span class="o">)</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span><span class="w"> </span><span class="n">h₁</span><span class="o">⟩</span><span class="w"> </span><span class="n">h'</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="o">(</span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h'</span><span class="o">)</span> <span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp">≠</span> <span class="n">y</span> <span class="bp">→</span> <span class="bp">¬</span><span class="n">y</span> <span class="bp">≤</span> <span class="n">x</span> <span class="o">:=</span> <span class="k">fun</span> <span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span> <span class="n">h₁</span><span class="o">⟩</span> <span class="n">h'</span> <span class="bp">↦</span> <span class="n">h₁</span> <span class="o">(</span><span class="n">le_antisymm</span> <span class="n">h₀</span> <span class="n">h'</span><span class="o">)</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span><span class="w"> </span><span class="n">h₁</span><span class="o">⟩</span><span class="w"> </span><span class="n">h'</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="o">(</span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h'</span><span class="o">)</span> </pre></div> </div> <p>In analogy to the <code class="docutils literal notranslate"><span class="pre">obtain</span></code> tactic, there is also a pattern-matching <code class="docutils literal notranslate"><span class="pre">have</span></code>:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp">≠</span> <span class="n">y</span><span class="o">)</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">y</span> <span class="bp">≤</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="k">have</span> <span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span> <span class="n">h₁</span><span class="o">⟩</span> <span class="o">:=</span> <span class="n">h</span> <span class="n">contrapose</span><span class="bp">!</span> <span class="n">h₁</span> <span class="n">exact</span> <span class="n">le_antisymm</span> <span class="n">h₀</span> <span class="n">h₁</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span><span class="w"> </span><span class="n">h₁</span><span class="o">⟩</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span><span class="w"> </span><span class="n">h₁</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span> </pre></div> </div> <p>In contrast to <code class="docutils literal notranslate"><span class="pre">rcases</span></code>, here the <code class="docutils literal notranslate"><span class="pre">have</span></code> tactic leaves <code class="docutils literal notranslate"><span class="pre">h</span></code> in the context. And even though we won’t use them, once again we have the computer scientists’ pattern-matching syntax:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp">≠</span> <span class="n">y</span><span class="o">)</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">y</span> <span class="bp">≤</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">cases</span> <span class="n">h</span> <span class="n">case</span> <span class="n">intro</span> <span class="n">h₀</span> <span class="n">h₁</span> <span class="bp">=></span> <span class="n">contrapose</span><span class="bp">!</span> <span class="n">h₁</span> <span class="n">exact</span> <span class="n">le_antisymm</span> <span class="n">h₀</span> <span class="n">h₁</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">cases</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">case</span><span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="bp">=></span> <span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span><span class="w"> </span><span class="n">h₁</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span> <span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp">≠</span> <span class="n">y</span><span class="o">)</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">y</span> <span class="bp">≤</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">cases</span> <span class="n">h</span> <span class="n">next</span> <span class="n">h₀</span> <span class="n">h₁</span> <span class="bp">=></span> <span class="n">contrapose</span><span class="bp">!</span> <span class="n">h₁</span> <span class="n">exact</span> <span class="n">le_antisymm</span> <span class="n">h₀</span> <span class="n">h₁</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">cases</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">next</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="bp">=></span> <span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span><span class="w"> </span><span class="n">h₁</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span> <span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp">≠</span> <span class="n">y</span><span class="o">)</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">y</span> <span class="bp">≤</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="k">match</span> <span class="n">h</span> <span class="k">with</span> <span class="bp">|</span> <span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span> <span class="n">h₁</span><span class="o">⟩</span> <span class="bp">=></span> <span class="n">contrapose</span><span class="bp">!</span> <span class="n">h₁</span> <span class="n">exact</span> <span class="n">le_antisymm</span> <span class="n">h₀</span> <span class="n">h₁</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="k">with</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span><span class="w"> </span><span class="n">h₁</span><span class="o">⟩</span><span class="w"> </span><span class="bp">=></span> <span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span><span class="w"> </span><span class="n">h₁</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span> </pre></div> </div> <p>In contrast to using an existential quantifier,
-
@@ -1169,47 +1170,47 @@ you can also extract proofs of the two componentsof a hypothesis <code class="docutils literal notranslate"><span class="pre">h</span> <span class="pre">:</span> <span class="pre">A</span> <span class="pre">∧</span> <span class="pre">B</span></code> by writing <code class="docutils literal notranslate"><span class="pre">h.left</span></code> and <code class="docutils literal notranslate"><span class="pre">h.right</span></code>, or, equivalently, <code class="docutils literal notranslate"><span class="pre">h.1</span></code> and <code class="docutils literal notranslate"><span class="pre">h.2</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp">≠</span> <span class="n">y</span><span class="o">)</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">y</span> <span class="bp">≤</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">h'</span> <span class="n">apply</span> <span class="n">h.right</span> <span class="n">exact</span> <span class="n">le_antisymm</span> <span class="n">h.left</span> <span class="n">h'</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h'</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">h.right</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h.left</span><span class="w"> </span><span class="n">h'</span> <span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp">≠</span> <span class="n">y</span><span class="o">)</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">y</span> <span class="bp">≤</span> <span class="n">x</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">h'</span> <span class="bp">↦</span> <span class="n">h.right</span> <span class="o">(</span><span class="n">le_antisymm</span> <span class="n">h.left</span> <span class="n">h'</span><span class="o">)</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">h'</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">h.right</span><span class="w"> </span><span class="o">(</span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h.left</span><span class="w"> </span><span class="n">h'</span><span class="o">)</span> </pre></div> </div> <p>Try using these techniques to come up with various ways of proving of the following:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">m</span> <span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">∣</span> <span class="n">n</span> <span class="bp">∧</span> <span class="n">m</span> <span class="bp">≠</span> <span class="n">n</span><span class="o">)</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">∣</span> <span class="n">n</span> <span class="bp">∧</span> <span class="bp">¬</span><span class="n">n</span> <span class="bp">∣</span> <span class="n">m</span> <span class="o">:=</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="bp">¬</span><span class="n">n</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>You can nest uses of <code class="docutils literal notranslate"><span class="pre">∃</span></code> and <code class="docutils literal notranslate"><span class="pre">∧</span></code> with anonymous constructors, <code class="docutils literal notranslate"><span class="pre">rintro</span></code>, and <code class="docutils literal notranslate"><span class="pre">rcases</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">,</span> <span class="mi">2</span> <span class="bp"><</span> <span class="n">x</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp"><</span> <span class="mi">4</span> <span class="o">:=</span> <span class="o">⟨</span><span class="mi">5</span> <span class="bp">/</span> <span class="mi">2</span><span class="o">,</span> <span class="kd">by</span> <span class="n">norm_num</span><span class="o">,</span> <span class="kd">by</span> <span class="n">norm_num</span><span class="o">⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">⟨</span><span class="mi">5</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="o">,</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span><span class="o">,</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span><span class="o">⟩</span> <span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="bp">∃</span> <span class="n">z</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">,</span> <span class="n">x</span> <span class="bp"><</span> <span class="n">z</span> <span class="bp">∧</span> <span class="n">z</span> <span class="bp"><</span> <span class="n">y</span><span class="o">)</span> <span class="bp">→</span> <span class="n">x</span> <span class="bp"><</span> <span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rintro</span> <span class="o">⟨</span><span class="n">z</span><span class="o">,</span> <span class="n">xltz</span><span class="o">,</span> <span class="n">zlty</span><span class="o">⟩</span> <span class="n">exact</span> <span class="n">lt_trans</span> <span class="n">xltz</span> <span class="n">zlty</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">∃</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="o">⟨</span><span class="n">z</span><span class="o">,</span><span class="w"> </span><span class="n">xltz</span><span class="o">,</span><span class="w"> </span><span class="n">zlty</span><span class="o">⟩</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">lt_trans</span><span class="w"> </span><span class="n">xltz</span><span class="w"> </span><span class="n">zlty</span> <span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="bp">∃</span> <span class="n">z</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">,</span> <span class="n">x</span> <span class="bp"><</span> <span class="n">z</span> <span class="bp">∧</span> <span class="n">z</span> <span class="bp"><</span> <span class="n">y</span><span class="o">)</span> <span class="bp">→</span> <span class="n">x</span> <span class="bp"><</span> <span class="n">y</span> <span class="o">:=</span> <span class="k">fun</span> <span class="o">⟨</span><span class="n">z</span><span class="o">,</span> <span class="n">xltz</span><span class="o">,</span> <span class="n">zlty</span><span class="o">⟩</span> <span class="bp">↦</span> <span class="n">lt_trans</span> <span class="n">xltz</span> <span class="n">zlty</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">∃</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="o">⟨</span><span class="n">z</span><span class="o">,</span><span class="w"> </span><span class="n">xltz</span><span class="o">,</span><span class="w"> </span><span class="n">zlty</span><span class="o">⟩</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">lt_trans</span><span class="w"> </span><span class="n">xltz</span><span class="w"> </span><span class="n">zlty</span> </pre></div> </div> <p>You can also use the <code class="docutils literal notranslate"><span class="pre">use</span></code> tactic:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">,</span> <span class="mi">2</span> <span class="bp"><</span> <span class="n">x</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp"><</span> <span class="mi">4</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">use</span> <span class="mi">5</span> <span class="bp">/</span> <span class="mi">2</span> <span class="n">constructor</span> <span class="bp"><;></span> <span class="n">norm_num</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span> <span class="w"> </span><span class="n">constructor</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">norm_num</span> <span class="kd">example</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">m</span> <span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">,</span> <span class="mi">4</span> <span class="bp"><</span> <span class="n">m</span> <span class="bp">∧</span> <span class="n">m</span> <span class="bp"><</span> <span class="n">n</span> <span class="bp">∧</span> <span class="n">n</span> <span class="bp"><</span> <span class="mi">10</span> <span class="bp">∧</span> <span class="n">Nat.Prime</span> <span class="n">m</span> <span class="bp">∧</span> <span class="n">Nat.Prime</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">use</span> <span class="mi">5</span> <span class="n">use</span> <span class="mi">7</span> <span class="n">norm_num</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">Nat.Prime</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">Nat.Prime</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="mi">5</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="mi">7</span> <span class="w"> </span><span class="n">norm_num</span> <span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp">≠</span> <span class="n">y</span> <span class="bp">→</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">∧</span> <span class="bp">¬</span><span class="n">y</span> <span class="bp">≤</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rintro</span> <span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span> <span class="n">h₁</span><span class="o">⟩</span> <span class="n">use</span> <span class="n">h₀</span> <span class="n">exact</span> <span class="k">fun</span> <span class="n">h'</span> <span class="bp">↦</span> <span class="n">h₁</span> <span class="o">(</span><span class="n">le_antisymm</span> <span class="n">h₀</span> <span class="n">h'</span><span class="o">)</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="o">⟨</span><span class="n">h₀</span><span class="o">,</span><span class="w"> </span><span class="n">h₁</span><span class="o">⟩</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">h₀</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">h'</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="o">(</span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h'</span><span class="o">)</span> </pre></div> </div> <p>In the first example, the semicolon after the <code class="docutils literal notranslate"><span class="pre">constructor</span></code> command tells Lean to use the
-
@@ -1223,16 +1224,16 @@ You can also use <code class="docutils literal notranslate"><span class="pre">cases</span></code> and friends.To prove an if-and-only-if statement, you can use <code class="docutils literal notranslate"><span class="pre">constructor</span></code> or angle brackets, just as you would if you were proving a conjunction.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span><span class="o">)</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">y</span> <span class="bp">≤</span> <span class="n">x</span> <span class="bp">↔</span> <span class="n">x</span> <span class="bp">≠</span> <span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">constructor</span> <span class="bp">·</span> <span class="n">contrapose</span><span class="bp">!</span> <span class="n">rintro</span> <span class="n">rfl</span> <span class="n">rfl</span> <span class="n">contrapose</span><span class="bp">!</span> <span class="n">exact</span> <span class="n">le_antisymm</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">constructor</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="n">rfl</span> <span class="w"> </span><span class="n">rfl</span> <span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h</span> <span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span><span class="o">)</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">y</span> <span class="bp">≤</span> <span class="n">x</span> <span class="bp">↔</span> <span class="n">x</span> <span class="bp">≠</span> <span class="n">y</span> <span class="o">:=</span> <span class="o">⟨</span><span class="k">fun</span> <span class="n">h₀</span> <span class="n">h₁</span> <span class="bp">↦</span> <span class="n">h₀</span> <span class="o">(</span><span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">h₁</span><span class="o">]),</span> <span class="k">fun</span> <span class="n">h₀</span> <span class="n">h₁</span> <span class="bp">↦</span> <span class="n">h₀</span> <span class="o">(</span><span class="n">le_antisymm</span> <span class="n">h</span> <span class="n">h₁</span><span class="o">)⟩</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">⟨</span><span class="k">fun</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="o">(</span><span class="kd">by</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">h₁</span><span class="o">]),</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="o">(</span><span class="n">le_antisymm</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="n">h₁</span><span class="o">)⟩</span> </pre></div> </div> <p>The last proof term is inscrutable. Remember that you can
-
@@ -1240,8 +1241,8 @@ use underscores while writing an expression like that tosee what Lean expects.</p> <p>Try out the various techniques and gadgets you have just seen in order to prove the following:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">∧</span> <span class="bp">¬</span><span class="n">y</span> <span class="bp">≤</span> <span class="n">x</span> <span class="bp">↔</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp">≠</span> <span class="n">y</span> <span class="o">:=</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="bp">¬</span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>For a more interesting exercise, show that for any
-
@@ -1249,12 +1250,12 @@ two real numbers <code class="docutils literal notranslate"><span class="pre">x</span></code> and <code class="docutils literal notranslate"><span class="pre">y</span></code>,<code class="docutils literal notranslate"><span class="pre">x^2</span> <span class="pre">+</span> <span class="pre">y^2</span> <span class="pre">=</span> <span class="pre">0</span></code> if and only if <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">=</span> <span class="pre">0</span></code> and <code class="docutils literal notranslate"><span class="pre">y</span> <span class="pre">=</span> <span class="pre">0</span></code>. We suggest proving an auxiliary lemma using <code class="docutils literal notranslate"><span class="pre">linarith</span></code>, <code class="docutils literal notranslate"><span class="pre">pow_two_nonneg</span></code>, and <code class="docutils literal notranslate"><span class="pre">pow_eq_zero</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">aux</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="n">y</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">=</span> <span class="mi">0</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="k">have</span> <span class="n">h'</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="n">pow_eq_zero</span> <span class="n">h'</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">aux</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">pow_eq_zero</span><span class="w"> </span><span class="n">h'</span> <span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="n">y</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">=</span> <span class="mi">0</span> <span class="bp">↔</span> <span class="n">x</span> <span class="bp">=</span> <span class="mi">0</span> <span class="bp">∧</span> <span class="n">y</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>In Lean, bi-implication leads a double-life.
-
@@ -1270,14 +1271,14 @@ replace an expression of the form <code class="docutils literal notranslate"><span class="pre">|x|</span> <span class="pre"><</span> <span class="pre">y</span></code>by the equivalent expression <code class="docutils literal notranslate"><span class="pre">-</span> <span class="pre">y</span> <span class="pre"><</span> <span class="pre">x</span> <span class="pre">∧</span> <span class="pre">x</span> <span class="pre"><</span> <span class="pre">y</span></code>, and in the one after that we use <code class="docutils literal notranslate"><span class="pre">Nat.dvd_gcd_iff</span></code> to replace an expression of the form <code class="docutils literal notranslate"><span class="pre">m</span> <span class="pre">∣</span> <span class="pre">Nat.gcd</span> <span class="pre">n</span> <span class="pre">k</span></code> by the equivalent expression <code class="docutils literal notranslate"><span class="pre">m</span> <span class="pre">∣</span> <span class="pre">n</span> <span class="pre">∧</span> <span class="pre">m</span> <span class="pre">∣</span> <span class="pre">k</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="bp">|</span><span class="n">x</span> <span class="bp">+</span> <span class="mi">3</span><span class="bp">|</span> <span class="bp"><</span> <span class="mi">5</span> <span class="bp">→</span> <span class="bp">-</span><span class="mi">8</span> <span class="bp"><</span> <span class="n">x</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp"><</span> <span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">abs_lt</span><span class="o">]</span> <span class="n">intro</span> <span class="n">h</span> <span class="n">constructor</span> <span class="bp"><;></span> <span class="n">linarith</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">3</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">-</span><span class="mi">8</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">abs_lt</span><span class="o">]</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">constructor</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">linarith</span> <span class="kd">example</span> <span class="o">:</span> <span class="mi">3</span> <span class="bp">∣</span> <span class="n">Nat.gcd</span> <span class="mi">6</span> <span class="mi">15</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">Nat.dvd_gcd_iff</span><span class="o">]</span> <span class="n">constructor</span> <span class="bp"><;></span> <span class="n">norm_num</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">Nat.gcd</span><span class="w"> </span><span class="mi">6</span><span class="w"> </span><span class="mi">15</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">Nat.dvd_gcd_iff</span><span class="o">]</span> <span class="w"> </span><span class="n">constructor</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">norm_num</span> </pre></div> </div> <p>See if you can use <code class="docutils literal notranslate"><span class="pre">rw</span></code> with the theorem below
-
@@ -1285,13 +1286,13 @@ to provide a short proof that negation is not anondecreasing function. (Note that <code class="docutils literal notranslate"><span class="pre">push_neg</span></code> won’t unfold definitions for you, so the <code class="docutils literal notranslate"><span class="pre">rw</span> <span class="pre">[Monotone]</span></code> in the proof of the theorem is needed.)</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">not_monotone_iff</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">Monotone</span> <span class="n">f</span> <span class="bp">↔</span> <span class="bp">∃</span> <span class="n">x</span> <span class="n">y</span><span class="o">,</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">y</span> <span class="bp">∧</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">></span> <span class="n">f</span> <span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">Monotone</span><span class="o">]</span> <span class="n">push_neg</span> <span class="n">rfl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">not_monotone_iff</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">Monotone</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">Monotone</span><span class="o">]</span> <span class="w"> </span><span class="n">push_neg</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">example</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">Monotone</span> <span class="k">fun</span> <span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">↦</span> <span class="bp">-</span><span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">Monotone</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="bp">-</span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>The remaining exercises in this section are designed
-
@@ -1306,12 +1307,12 @@ Lean axiomatizes the associated strict pre-order by<code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre"><</span> <span class="pre">b</span> <span class="pre">↔</span> <span class="pre">a</span> <span class="pre">≤</span> <span class="pre">b</span> <span class="pre">∧</span> <span class="pre">¬</span> <span class="pre">b</span> <span class="pre">≤</span> <span class="pre">a</span></code>. Show that if <code class="docutils literal notranslate"><span class="pre">≤</span></code> is a partial order, then <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre"><</span> <span class="pre">b</span></code> is equivalent to <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">≤</span> <span class="pre">b</span> <span class="pre">∧</span> <span class="pre">a</span> <span class="pre">≠</span> <span class="pre">b</span></code>:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">PartialOrder</span> <span class="n">α</span><span class="o">]</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">α</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">PartialOrder</span><span class="w"> </span><span class="n">α</span><span class="o">]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">b</span> <span class="bp">↔</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">∧</span> <span class="n">a</span> <span class="bp">≠</span> <span class="n">b</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">lt_iff_le_not_le</span><span class="o">]</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">lt_iff_le_not_le</span><span class="o">]</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p id="index-20">Beyond logical operations, you do not need
-
@@ -1327,16 +1328,16 @@ We will come back to the simplifier later,but here we are only relying on the fact that it will use the indicated lemma repeatedly, even if it needs to be instantiated to different values.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Preorder</span> <span class="n">α</span><span class="o">]</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">α</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Preorder</span><span class="w"> </span><span class="n">α</span><span class="o">]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span> <span class="kd">example</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">a</span> <span class="bp"><</span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">lt_iff_le_not_le</span><span class="o">]</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">lt_iff_le_not_le</span><span class="o">]</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">b</span> <span class="bp">→</span> <span class="n">b</span> <span class="bp"><</span> <span class="n">c</span> <span class="bp">→</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">c</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="n">only</span> <span class="o">[</span><span class="n">lt_iff_le_not_le</span><span class="o">]</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="n">only</span><span class="w"> </span><span class="o">[</span><span class="n">lt_iff_le_not_le</span><span class="o">]</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> </section>
-
@@ -1346,15 +1347,15 @@ <p id="index-21">The canonical way to prove a disjunction <code class="docutils literal notranslate"><span class="pre">A</span> <span class="pre">∨</span> <span class="pre">B</span></code> is to prove<code class="docutils literal notranslate"><span class="pre">A</span></code> or to prove <code class="docutils literal notranslate"><span class="pre">B</span></code>. The <code class="docutils literal notranslate"><span class="pre">left</span></code> tactic chooses <code class="docutils literal notranslate"><span class="pre">A</span></code>, and the <code class="docutils literal notranslate"><span class="pre">right</span></code> tactic chooses <code class="docutils literal notranslate"><span class="pre">B</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">y</span> <span class="bp">></span> <span class="n">x</span> <span class="bp">^</span> <span class="mi">2</span><span class="o">)</span> <span class="o">:</span> <span class="n">y</span> <span class="bp">></span> <span class="mi">0</span> <span class="bp">∨</span> <span class="n">y</span> <span class="bp"><</span> <span class="bp">-</span><span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">left</span> <span class="n">linarith</span> <span class="o">[</span><span class="n">pow_two_nonneg</span> <span class="n">x</span><span class="o">]</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">-</span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">left</span> <span class="w"> </span><span class="n">linarith</span><span class="w"> </span><span class="o">[</span><span class="n">pow_two_nonneg</span><span class="w"> </span><span class="n">x</span><span class="o">]</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">-</span><span class="n">y</span> <span class="bp">></span> <span class="n">x</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">)</span> <span class="o">:</span> <span class="n">y</span> <span class="bp">></span> <span class="mi">0</span> <span class="bp">∨</span> <span class="n">y</span> <span class="bp"><</span> <span class="bp">-</span><span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">right</span> <span class="n">linarith</span> <span class="o">[</span><span class="n">pow_two_nonneg</span> <span class="n">x</span><span class="o">]</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">-</span><span class="n">y</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">-</span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">right</span> <span class="w"> </span><span class="n">linarith</span><span class="w"> </span><span class="o">[</span><span class="n">pow_two_nonneg</span><span class="w"> </span><span class="n">x</span><span class="o">]</span> </pre></div> </div> <p>We cannot use an anonymous constructor to construct a proof
-
@@ -1365,11 +1366,11 @@ <code class="docutils literal notranslate"><span class="pre">Or.inl</span></code> and <code class="docutils literal notranslate"><span class="pre">Or.inr</span></code> insteadto make the choice explicitly. Here, <code class="docutils literal notranslate"><span class="pre">inl</span></code> is short for “introduction left” and <code class="docutils literal notranslate"><span class="pre">inr</span></code> is short for “introduction right.”</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">y</span> <span class="bp">></span> <span class="mi">0</span><span class="o">)</span> <span class="o">:</span> <span class="n">y</span> <span class="bp">></span> <span class="mi">0</span> <span class="bp">∨</span> <span class="n">y</span> <span class="bp"><</span> <span class="bp">-</span><span class="mi">1</span> <span class="o">:=</span> <span class="n">Or.inl</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">-</span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Or.inl</span><span class="w"> </span><span class="n">h</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">y</span> <span class="bp"><</span> <span class="bp">-</span><span class="mi">1</span><span class="o">)</span> <span class="o">:</span> <span class="n">y</span> <span class="bp">></span> <span class="mi">0</span> <span class="bp">∨</span> <span class="n">y</span> <span class="bp"><</span> <span class="bp">-</span><span class="mi">1</span> <span class="o">:=</span> <span class="n">Or.inr</span> <span class="n">h</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">-</span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">-</span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Or.inr</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>It may seem strange to prove a disjunction by proving one side
-
@@ -1390,12 +1391,12 @@ the <code class="docutils literal notranslate"><span class="pre">rcases</span></code> tactic carries out a proof by cases.As usual, we can tell Lean what names to use for the hypotheses. In the next example, we tell Lean to use the name <code class="docutils literal notranslate"><span class="pre">h</span></code> on each branch.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">x</span> <span class="bp"><</span> <span class="bp">|</span><span class="n">y</span><span class="bp">|</span> <span class="bp">→</span> <span class="n">x</span> <span class="bp"><</span> <span class="n">y</span> <span class="bp">∨</span> <span class="n">x</span> <span class="bp"><</span> <span class="bp">-</span><span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rcases</span> <span class="n">le_or_gt</span> <span class="mi">0</span> <span class="n">y</span> <span class="k">with</span> <span class="n">h</span> <span class="bp">|</span> <span class="n">h</span> <span class="bp">·</span> <span class="n">rw</span> <span class="o">[</span><span class="n">abs_of_nonneg</span> <span class="n">h</span><span class="o">]</span> <span class="n">intro</span> <span class="n">h</span><span class="bp">;</span> <span class="n">left</span><span class="bp">;</span> <span class="n">exact</span> <span class="n">h</span> <span class="bp">·</span> <span class="n">rw</span> <span class="o">[</span><span class="n">abs_of_neg</span> <span class="n">h</span><span class="o">]</span> <span class="n">intro</span> <span class="n">h</span><span class="bp">;</span> <span class="n">right</span><span class="bp">;</span> <span class="n">exact</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">-</span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">le_or_gt</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">abs_of_nonneg</span><span class="w"> </span><span class="n">h</span><span class="o">]</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span><span class="bp">;</span><span class="w"> </span><span class="n">left</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">abs_of_neg</span><span class="w"> </span><span class="n">h</span><span class="o">]</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span><span class="bp">;</span><span class="w"> </span><span class="n">right</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>Notice that the pattern changes from <code class="docutils literal notranslate"><span class="pre">⟨h₀,</span> <span class="pre">h₁⟩</span></code> in the case of
-
@@ -1416,14 +1417,14 @@ <p>Lean also supports the computer scientists’ pattern-matchingsyntax for disjunction. Now the <code class="docutils literal notranslate"><span class="pre">cases</span></code> tactic is more attractive, because it allows us to name each <code class="docutils literal notranslate"><span class="pre">case</span></code>, and name the hypothesis that is introduced closer to where it is used.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">x</span> <span class="bp"><</span> <span class="bp">|</span><span class="n">y</span><span class="bp">|</span> <span class="bp">→</span> <span class="n">x</span> <span class="bp"><</span> <span class="n">y</span> <span class="bp">∨</span> <span class="n">x</span> <span class="bp"><</span> <span class="bp">-</span><span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">cases</span> <span class="n">le_or_gt</span> <span class="mi">0</span> <span class="n">y</span> <span class="n">case</span> <span class="n">inl</span> <span class="n">h</span> <span class="bp">=></span> <span class="n">rw</span> <span class="o">[</span><span class="n">abs_of_nonneg</span> <span class="n">h</span><span class="o">]</span> <span class="n">intro</span> <span class="n">h</span><span class="bp">;</span> <span class="n">left</span><span class="bp">;</span> <span class="n">exact</span> <span class="n">h</span> <span class="n">case</span> <span class="n">inr</span> <span class="n">h</span> <span class="bp">=></span> <span class="n">rw</span> <span class="o">[</span><span class="n">abs_of_neg</span> <span class="n">h</span><span class="o">]</span> <span class="n">intro</span> <span class="n">h</span><span class="bp">;</span> <span class="n">right</span><span class="bp">;</span> <span class="n">exact</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">-</span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">cases</span><span class="w"> </span><span class="n">le_or_gt</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="n">y</span> <span class="w"> </span><span class="n">case</span><span class="w"> </span><span class="n">inl</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="bp">=></span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">abs_of_nonneg</span><span class="w"> </span><span class="n">h</span><span class="o">]</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span><span class="bp">;</span><span class="w"> </span><span class="n">left</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">case</span><span class="w"> </span><span class="n">inr</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="bp">=></span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">abs_of_neg</span><span class="w"> </span><span class="n">h</span><span class="o">]</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span><span class="bp">;</span><span class="w"> </span><span class="n">right</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>The names <code class="docutils literal notranslate"><span class="pre">inl</span></code> and <code class="docutils literal notranslate"><span class="pre">inr</span></code> are short for “intro left” and “intro right,”
-
@@ -1431,23 +1432,23 @@ respectively. Using <code class="docutils literal notranslate"><span class="pre">case</span></code> has the advantage that you can prove thecases in either order; Lean uses the tag to find the relevant goal. If you don’t care about that, you can use <code class="docutils literal notranslate"><span class="pre">next</span></code>, or <code class="docutils literal notranslate"><span class="pre">match</span></code>, or even a pattern-matching <code class="docutils literal notranslate"><span class="pre">have</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">x</span> <span class="bp"><</span> <span class="bp">|</span><span class="n">y</span><span class="bp">|</span> <span class="bp">→</span> <span class="n">x</span> <span class="bp"><</span> <span class="n">y</span> <span class="bp">∨</span> <span class="n">x</span> <span class="bp"><</span> <span class="bp">-</span><span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">cases</span> <span class="n">le_or_gt</span> <span class="mi">0</span> <span class="n">y</span> <span class="n">next</span> <span class="n">h</span> <span class="bp">=></span> <span class="n">rw</span> <span class="o">[</span><span class="n">abs_of_nonneg</span> <span class="n">h</span><span class="o">]</span> <span class="n">intro</span> <span class="n">h</span><span class="bp">;</span> <span class="n">left</span><span class="bp">;</span> <span class="n">exact</span> <span class="n">h</span> <span class="n">next</span> <span class="n">h</span> <span class="bp">=></span> <span class="n">rw</span> <span class="o">[</span><span class="n">abs_of_neg</span> <span class="n">h</span><span class="o">]</span> <span class="n">intro</span> <span class="n">h</span><span class="bp">;</span> <span class="n">right</span><span class="bp">;</span> <span class="n">exact</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">-</span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">cases</span><span class="w"> </span><span class="n">le_or_gt</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="n">y</span> <span class="w"> </span><span class="n">next</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="bp">=></span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">abs_of_nonneg</span><span class="w"> </span><span class="n">h</span><span class="o">]</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span><span class="bp">;</span><span class="w"> </span><span class="n">left</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">next</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="bp">=></span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">abs_of_neg</span><span class="w"> </span><span class="n">h</span><span class="o">]</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span><span class="bp">;</span><span class="w"> </span><span class="n">right</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">x</span> <span class="bp"><</span> <span class="bp">|</span><span class="n">y</span><span class="bp">|</span> <span class="bp">→</span> <span class="n">x</span> <span class="bp"><</span> <span class="n">y</span> <span class="bp">∨</span> <span class="n">x</span> <span class="bp"><</span> <span class="bp">-</span><span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="k">match</span> <span class="n">le_or_gt</span> <span class="mi">0</span> <span class="n">y</span> <span class="k">with</span> <span class="bp">|</span> <span class="n">Or.inl</span> <span class="n">h</span> <span class="bp">=></span> <span class="n">rw</span> <span class="o">[</span><span class="n">abs_of_nonneg</span> <span class="n">h</span><span class="o">]</span> <span class="n">intro</span> <span class="n">h</span><span class="bp">;</span> <span class="n">left</span><span class="bp">;</span> <span class="n">exact</span> <span class="n">h</span> <span class="bp">|</span> <span class="n">Or.inr</span> <span class="n">h</span> <span class="bp">=></span> <span class="n">rw</span> <span class="o">[</span><span class="n">abs_of_neg</span> <span class="n">h</span><span class="o">]</span> <span class="n">intro</span> <span class="n">h</span><span class="bp">;</span> <span class="n">right</span><span class="bp">;</span> <span class="n">exact</span> <span class="n">h</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">-</span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">le_or_gt</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="k">with</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">Or.inl</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="bp">=></span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">abs_of_nonneg</span><span class="w"> </span><span class="n">h</span><span class="o">]</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span><span class="bp">;</span><span class="w"> </span><span class="n">left</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">Or.inr</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="bp">=></span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">abs_of_neg</span><span class="w"> </span><span class="n">h</span><span class="o">]</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span><span class="bp">;</span><span class="w"> </span><span class="n">right</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>In the case of <code class="docutils literal notranslate"><span class="pre">match</span></code>, we need to use the full names
-
@@ -1457,54 +1458,54 @@ cases of a disjunction.</p><p>Try proving the triangle inequality using the first two theorems in the next snippet. They are given the same names they have in Mathlib.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">namespace</span> <span class="n">MyAbs</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">namespace</span><span class="w"> </span><span class="n">MyAbs</span> <span class="kd">theorem</span> <span class="n">le_abs_self</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≤</span> <span class="bp">|</span><span class="n">x</span><span class="bp">|</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">le_abs_self</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">theorem</span> <span class="n">neg_le_abs_self</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="bp">-</span><span class="n">x</span> <span class="bp">≤</span> <span class="bp">|</span><span class="n">x</span><span class="bp">|</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">neg_le_abs_self</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">-</span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">theorem</span> <span class="n">abs_add</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="bp">|</span><span class="n">x</span> <span class="bp">+</span> <span class="n">y</span><span class="bp">|</span> <span class="bp">≤</span> <span class="bp">|</span><span class="n">x</span><span class="bp">|</span> <span class="bp">+</span> <span class="bp">|</span><span class="n">y</span><span class="bp">|</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">abs_add</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>In case you enjoyed these (pun intended) and you want more practice with disjunction, try these.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">lt_abs</span> <span class="o">:</span> <span class="n">x</span> <span class="bp"><</span> <span class="bp">|</span><span class="n">y</span><span class="bp">|</span> <span class="bp">↔</span> <span class="n">x</span> <span class="bp"><</span> <span class="n">y</span> <span class="bp">∨</span> <span class="n">x</span> <span class="bp"><</span> <span class="bp">-</span><span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">lt_abs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">|</span><span class="n">y</span><span class="bp">|</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">-</span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">theorem</span> <span class="n">abs_lt</span> <span class="o">:</span> <span class="bp">|</span><span class="n">x</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">y</span> <span class="bp">↔</span> <span class="bp">-</span><span class="n">y</span> <span class="bp"><</span> <span class="n">x</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp"><</span> <span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">abs_lt</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">x</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">-</span><span class="n">y</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>You can also use <code class="docutils literal notranslate"><span class="pre">rcases</span></code> and <code class="docutils literal notranslate"><span class="pre">rintro</span></code> with nested disjunctions. When these result in a genuine case split with multiple goals, the patterns for each new goal are separated by a vertical bar.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">≠</span> <span class="mi">0</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp"><</span> <span class="mi">0</span> <span class="bp">∨</span> <span class="n">x</span> <span class="bp">></span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rcases</span> <span class="n">lt_trichotomy</span> <span class="n">x</span> <span class="mi">0</span> <span class="k">with</span> <span class="n">xlt</span> <span class="bp">|</span> <span class="n">xeq</span> <span class="bp">|</span> <span class="n">xgt</span> <span class="bp">·</span> <span class="n">left</span> <span class="n">exact</span> <span class="n">xlt</span> <span class="bp">·</span> <span class="n">contradiction</span> <span class="bp">·</span> <span class="n">right</span><span class="bp">;</span> <span class="n">exact</span> <span class="n">xgt</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">lt_trichotomy</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">xlt</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">xeq</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">xgt</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">left</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">xlt</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">contradiction</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">right</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">xgt</span> </pre></div> </div> <p>You can still nest patterns and use the <code class="docutils literal notranslate"><span class="pre">rfl</span></code> keyword to substitute equations:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">m</span> <span class="n">n</span> <span class="n">k</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">∣</span> <span class="n">n</span> <span class="bp">∨</span> <span class="n">m</span> <span class="bp">∣</span> <span class="n">k</span><span class="o">)</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">∣</span> <span class="n">n</span> <span class="bp">*</span> <span class="n">k</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rcases</span> <span class="n">h</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">a</span><span class="o">,</span> <span class="n">rfl</span><span class="o">⟩</span> <span class="bp">|</span> <span class="o">⟨</span><span class="n">b</span><span class="o">,</span> <span class="n">rfl</span><span class="o">⟩</span> <span class="bp">·</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mul_assoc</span><span class="o">]</span> <span class="n">apply</span> <span class="n">dvd_mul_right</span> <span class="bp">·</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mul_comm</span><span class="o">,</span> <span class="n">mul_assoc</span><span class="o">]</span> <span class="n">apply</span> <span class="n">dvd_mul_right</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">k</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">rfl</span><span class="o">⟩</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="o">⟨</span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">rfl</span><span class="o">⟩</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mul_assoc</span><span class="o">]</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">dvd_mul_right</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mul_comm</span><span class="o">,</span><span class="w"> </span><span class="n">mul_assoc</span><span class="o">]</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">dvd_mul_right</span> </pre></div> </div> <p>See if you can prove the following with a single (long) line. Use <code class="docutils literal notranslate"><span class="pre">rcases</span></code> to unpack the hypotheses and split on cases, and use a semicolon and <code class="docutils literal notranslate"><span class="pre">linarith</span></code> to solve each branch.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">z</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span> <span class="n">y</span><span class="o">,</span> <span class="n">z</span> <span class="bp">=</span> <span class="n">x</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="n">y</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">∨</span> <span class="n">z</span> <span class="bp">=</span> <span class="n">x</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="n">y</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">)</span> <span class="o">:</span> <span class="n">z</span> <span class="bp">≥</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="o">,</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>On the real numbers, an equation <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">*</span> <span class="pre">y</span> <span class="pre">=</span> <span class="pre">0</span></code>
-
@@ -1512,11 +1513,11 @@ tells us that <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">=</span> <span class="pre">0</span></code> or <code class="docutils literal notranslate"><span class="pre">y</span> <span class="pre">=</span> <span class="pre">0</span></code>.In Mathlib, this fact is known as <code class="docutils literal notranslate"><span class="pre">eq_zero_or_eq_zero_of_mul_eq_zero</span></code>, and it is another nice example of how a disjunction can arise. See if you can use it to prove the following:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">=</span> <span class="mi">1</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">=</span> <span class="mi">1</span> <span class="bp">∨</span> <span class="n">x</span> <span class="bp">=</span> <span class="bp">-</span><span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">-</span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">=</span> <span class="n">y</span> <span class="bp">^</span> <span class="mi">2</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">=</span> <span class="n">y</span> <span class="bp">∨</span> <span class="n">x</span> <span class="bp">=</span> <span class="bp">-</span><span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">-</span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Remember that you can use the <code class="docutils literal notranslate"><span class="pre">ring</span></code> tactic to help
-
@@ -1534,14 +1535,14 @@ says that the real numbers have no nontrivial zero divisors.A commutative ring with this property is called an <em>integral domain</em>. Your proofs of the two theorems above should work equally well in any integral domain:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="o">[</span><span class="n">IsDomain</span> <span class="n">R</span><span class="o">]</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">IsDomain</span><span class="w"> </span><span class="n">R</span><span class="o">]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">=</span> <span class="mi">1</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">=</span> <span class="mi">1</span> <span class="bp">∨</span> <span class="n">x</span> <span class="bp">=</span> <span class="bp">-</span><span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">-</span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">=</span> <span class="n">y</span> <span class="bp">^</span> <span class="mi">2</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">=</span> <span class="n">y</span> <span class="bp">∨</span> <span class="n">x</span> <span class="bp">=</span> <span class="bp">-</span><span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">-</span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>In fact, if you are careful, you can prove the first
-
@@ -1553,19 +1554,19 @@ depending on whether some statement is true or not.For any proposition <code class="docutils literal notranslate"><span class="pre">P</span></code>, we can use <code class="docutils literal notranslate"><span class="pre">em</span> <span class="pre">P</span> <span class="pre">:</span> <span class="pre">P</span> <span class="pre">∨</span> <span class="pre">¬</span> <span class="pre">P</span></code>. The name <code class="docutils literal notranslate"><span class="pre">em</span></code> is short for “excluded middle.”</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">P</span> <span class="o">:</span> <span class="kt">Prop</span><span class="o">)</span> <span class="o">:</span> <span class="bp">¬¬</span><span class="n">P</span> <span class="bp">→</span> <span class="n">P</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">h</span> <span class="n">cases</span> <span class="n">em</span> <span class="n">P</span> <span class="bp">·</span> <span class="n">assumption</span> <span class="bp">·</span> <span class="n">contradiction</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">P</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬¬</span><span class="n">P</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">cases</span><span class="w"> </span><span class="n">em</span><span class="w"> </span><span class="n">P</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">assumption</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">contradiction</span> </pre></div> </div> <p id="index-23">Alternatively, you can use the <code class="docutils literal notranslate"><span class="pre">by_cases</span></code> tactic.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">P</span> <span class="o">:</span> <span class="kt">Prop</span><span class="o">)</span> <span class="o">:</span> <span class="bp">¬¬</span><span class="n">P</span> <span class="bp">→</span> <span class="n">P</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">h</span> <span class="n">by_cases</span> <span class="n">h'</span> <span class="o">:</span> <span class="n">P</span> <span class="bp">·</span> <span class="n">assumption</span> <span class="n">contradiction</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">P</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬¬</span><span class="n">P</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">by_cases</span><span class="w"> </span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">P</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">assumption</span> <span class="w"> </span><span class="n">contradiction</span> </pre></div> </div> <p>Notice that the <code class="docutils literal notranslate"><span class="pre">by_cases</span></code> tactic lets you
-
@@ -1577,8 +1578,8 @@ If you leave out the label,Lean uses <code class="docutils literal notranslate"><span class="pre">h</span></code> by default. Try proving the following equivalence, using <code class="docutils literal notranslate"><span class="pre">by_cases</span></code> to establish one direction.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">P</span> <span class="n">Q</span> <span class="o">:</span> <span class="kt">Prop</span><span class="o">)</span> <span class="o">:</span> <span class="n">P</span> <span class="bp">→</span> <span class="n">Q</span> <span class="bp">↔</span> <span class="bp">¬</span><span class="n">P</span> <span class="bp">∨</span> <span class="n">Q</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">P</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">¬</span><span class="n">P</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> </section>
-
@@ -1593,8 +1594,8 @@ remains within <span class="math notranslate nohighlight">\(\varepsilon\)</span> of <span class="math notranslate nohighlight">\(a\)</span>,that is, there is a number <span class="math notranslate nohighlight">\(N\)</span> such that for every <span class="math notranslate nohighlight">\(n \ge N\)</span>, <span class="math notranslate nohighlight">\(| s_n - a | < \varepsilon\)</span>. In Lean, we can render this as follows:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">ConvergesTo</span> <span class="o">(</span><span class="n">s</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:=</span> <span class="bp">∀</span> <span class="n">ε</span> <span class="bp">></span> <span class="mi">0</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">N</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">n</span> <span class="bp">≥</span> <span class="n">N</span><span class="o">,</span> <span class="bp">|</span><span class="n">s</span> <span class="n">n</span> <span class="bp">-</span> <span class="n">a</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">ε</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="bp">|</span><span class="n">s</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">a</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span> </pre></div> </div> <p>The notation <code class="docutils literal notranslate"><span class="pre">∀</span> <span class="pre">ε</span> <span class="pre">></span> <span class="pre">0,</span> <span class="pre">...</span></code> is a convenient abbreviation
-
@@ -1614,9 +1615,9 @@ value for every <span class="math notranslate nohighlight">\(x\)</span>.The <code class="docutils literal notranslate"><span class="pre">ext</span></code> tactic enables us to prove an equation between functions by proving that their values are the same at all the values of their arguments.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="k">fun</span> <span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">↦</span> <span class="o">(</span><span class="n">x</span> <span class="bp">+</span> <span class="n">y</span><span class="o">)</span> <span class="bp">^</span> <span class="mi">2</span><span class="o">)</span> <span class="bp">=</span> <span class="k">fun</span> <span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">↦</span> <span class="n">x</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="mi">2</span> <span class="bp">*</span> <span class="n">x</span> <span class="bp">*</span> <span class="n">y</span> <span class="bp">+</span> <span class="n">y</span> <span class="bp">^</span> <span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ext</span> <span class="n">ring</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">ext</span> <span class="w"> </span><span class="n">ring</span> </pre></div> </div> <p id="index-25">We’ll see later that <code class="docutils literal notranslate"><span class="pre">ext</span></code> is actually more general, and also one can
-
@@ -1626,9 +1627,9 @@ above proof.The second tactic, the <code class="docutils literal notranslate"><span class="pre">congr</span></code> tactic, allows us to prove an equation between two expressions by reconciling the parts that are different:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="bp">|</span><span class="n">a</span><span class="bp">|</span> <span class="bp">=</span> <span class="bp">|</span><span class="n">a</span> <span class="bp">-</span> <span class="n">b</span> <span class="bp">+</span> <span class="n">b</span><span class="bp">|</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">congr</span> <span class="n">ring</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="bp">|</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">congr</span> <span class="w"> </span><span class="n">ring</span> </pre></div> </div> <p>Here the <code class="docutils literal notranslate"><span class="pre">congr</span></code> tactic peels off the <code class="docutils literal notranslate"><span class="pre">abs</span></code> on each side,
-
@@ -1644,10 +1645,10 @@ Instead, the <code class="docutils literal notranslate"><span class="pre">convert</span></code> tactic lets us apply the theoremas it is, and leaves us with the task of proving the equations that are needed to make the goal match.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">a</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="mi">1</span> <span class="bp"><</span> <span class="n">a</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">convert</span> <span class="o">(</span><span class="n">mul_lt_mul_right</span> <span class="n">_</span><span class="o">)</span><span class="bp">.</span><span class="mi">2</span> <span class="n">h</span> <span class="bp">·</span> <span class="n">rw</span> <span class="o">[</span><span class="n">one_mul</span><span class="o">]</span> <span class="n">exact</span> <span class="n">lt_trans</span> <span class="n">zero_lt_one</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">convert</span><span class="w"> </span><span class="o">(</span><span class="n">mul_lt_mul_right</span><span class="w"> </span><span class="n">_</span><span class="o">)</span><span class="bp">.</span><span class="mi">2</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">one_mul</span><span class="o">]</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">lt_trans</span><span class="w"> </span><span class="n">zero_lt_one</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>This example illustrates another useful trick: when we apply an
-
@@ -1656,12 +1657,12 @@ and Lean can’t fill it in for us automatically,it simply leaves it for us as another goal.</p> <p>The following shows that any constant sequence <span class="math notranslate nohighlight">\(a, a, a, \ldots\)</span> converges.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">convergesTo_const</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">ConvergesTo</span> <span class="o">(</span><span class="k">fun</span> <span class="n">x</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">↦</span> <span class="n">a</span><span class="o">)</span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">ε</span> <span class="n">εpos</span> <span class="n">use</span> <span class="mi">0</span> <span class="n">intro</span> <span class="n">n</span> <span class="n">nge</span> <span class="n">rw</span> <span class="o">[</span><span class="n">sub_self</span><span class="o">,</span> <span class="n">abs_zero</span><span class="o">]</span> <span class="n">apply</span> <span class="n">εpos</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">convergesTo_const</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="n">εpos</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="mi">0</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">nge</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">sub_self</span><span class="o">,</span><span class="w"> </span><span class="n">abs_zero</span><span class="o">]</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">εpos</span> </pre></div> </div> <p>Lean has a tactic, <code class="docutils literal notranslate"><span class="pre">simp</span></code>, which can often save you the
-
@@ -1685,16 +1686,16 @@ the sequence <code class="docutils literal notranslate"><span class="pre">fun</span> <span class="pre">n</span> <span class="pre">↦</span> <span class="pre">s</span> <span class="pre">n</span> <span class="pre">+</span> <span class="pre">t</span> <span class="pre">n</span></code> should be within <code class="docutils literal notranslate"><span class="pre">ε</span></code>of <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">+</span> <span class="pre">b</span></code>. The following example begins to implement this strategy. See if you can finish it off.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">convergesTo_add</span> <span class="o">{</span><span class="n">s</span> <span class="n">t</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">cs</span> <span class="o">:</span> <span class="n">ConvergesTo</span> <span class="n">s</span> <span class="n">a</span><span class="o">)</span> <span class="o">(</span><span class="n">ct</span> <span class="o">:</span> <span class="n">ConvergesTo</span> <span class="n">t</span> <span class="n">b</span><span class="o">)</span> <span class="o">:</span> <span class="n">ConvergesTo</span> <span class="o">(</span><span class="k">fun</span> <span class="n">n</span> <span class="bp">↦</span> <span class="n">s</span> <span class="n">n</span> <span class="bp">+</span> <span class="n">t</span> <span class="n">n</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">ε</span> <span class="n">εpos</span> <span class="n">dsimp</span> <span class="c1">-- this line is not needed but cleans up the goal a bit.</span> <span class="k">have</span> <span class="n">ε2pos</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">ε</span> <span class="bp">/</span> <span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">linarith</span> <span class="n">rcases</span> <span class="n">cs</span> <span class="o">(</span><span class="n">ε</span> <span class="bp">/</span> <span class="mi">2</span><span class="o">)</span> <span class="n">ε2pos</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">Ns</span><span class="o">,</span> <span class="n">hs</span><span class="o">⟩</span> <span class="n">rcases</span> <span class="n">ct</span> <span class="o">(</span><span class="n">ε</span> <span class="bp">/</span> <span class="mi">2</span><span class="o">)</span> <span class="n">ε2pos</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">Nt</span><span class="o">,</span> <span class="n">ht</span><span class="o">⟩</span> <span class="n">use</span> <span class="n">max</span> <span class="n">Ns</span> <span class="n">Nt</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">convergesTo_add</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span> <span class="w"> </span><span class="o">(</span><span class="n">cs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ct</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="n">εpos</span> <span class="w"> </span><span class="n">dsimp</span><span class="w"> </span><span class="c1">-- this line is not needed but cleans up the goal a bit.</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">ε2pos</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">linarith</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">cs</span><span class="w"> </span><span class="o">(</span><span class="n">ε</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="n">ε2pos</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">Ns</span><span class="o">,</span><span class="w"> </span><span class="n">hs</span><span class="o">⟩</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">ct</span><span class="w"> </span><span class="o">(</span><span class="n">ε</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="n">ε2pos</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">Nt</span><span class="o">,</span><span class="w"> </span><span class="n">ht</span><span class="o">⟩</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">max</span><span class="w"> </span><span class="n">Ns</span><span class="w"> </span><span class="n">Nt</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>As hints, you can use <code class="docutils literal notranslate"><span class="pre">le_of_max_le_left</span></code> and <code class="docutils literal notranslate"><span class="pre">le_of_max_le_right</span></code>,
-
@@ -1716,27 +1717,27 @@ is equal to zero or not.We have taken care of the zero case, and we have left you to prove the result with the extra assumption that <code class="docutils literal notranslate"><span class="pre">c</span></code> is nonzero.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">convergesTo_mul_const</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">{</span><span class="n">a</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">c</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">cs</span> <span class="o">:</span> <span class="n">ConvergesTo</span> <span class="n">s</span> <span class="n">a</span><span class="o">)</span> <span class="o">:</span> <span class="n">ConvergesTo</span> <span class="o">(</span><span class="k">fun</span> <span class="n">n</span> <span class="bp">↦</span> <span class="n">c</span> <span class="bp">*</span> <span class="n">s</span> <span class="n">n</span><span class="o">)</span> <span class="o">(</span><span class="n">c</span> <span class="bp">*</span> <span class="n">a</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">by_cases</span> <span class="n">h</span> <span class="o">:</span> <span class="n">c</span> <span class="bp">=</span> <span class="mi">0</span> <span class="bp">·</span> <span class="n">convert</span> <span class="n">convergesTo_const</span> <span class="mi">0</span> <span class="bp">·</span> <span class="n">rw</span> <span class="o">[</span><span class="n">h</span><span class="o">]</span> <span class="n">ring</span> <span class="n">rw</span> <span class="o">[</span><span class="n">h</span><span class="o">]</span> <span class="n">ring</span> <span class="k">have</span> <span class="n">acpos</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="bp">|</span><span class="n">c</span><span class="bp">|</span> <span class="o">:=</span> <span class="n">abs_pos.mpr</span> <span class="n">h</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">convergesTo_mul_const</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">cs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">by_cases</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">convert</span><span class="w"> </span><span class="n">convergesTo_const</span><span class="w"> </span><span class="mi">0</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">h</span><span class="o">]</span> <span class="w"> </span><span class="n">ring</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">h</span><span class="o">]</span> <span class="w"> </span><span class="n">ring</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">acpos</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">|</span><span class="n">c</span><span class="bp">|</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">abs_pos.mpr</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>The next theorem is also independently interesting: it shows that a convergent sequence is eventually bounded in absolute value. We have started you off; see if you can finish it.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">exists_abs_le_of_convergesTo</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">{</span><span class="n">a</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">cs</span> <span class="o">:</span> <span class="n">ConvergesTo</span> <span class="n">s</span> <span class="n">a</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">N</span> <span class="n">b</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">n</span><span class="o">,</span> <span class="n">N</span> <span class="bp">≤</span> <span class="n">n</span> <span class="bp">→</span> <span class="bp">|</span><span class="n">s</span> <span class="n">n</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">b</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rcases</span> <span class="n">cs</span> <span class="mi">1</span> <span class="n">zero_lt_one</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">N</span><span class="o">,</span> <span class="n">h</span><span class="o">⟩</span> <span class="n">use</span> <span class="n">N</span><span class="o">,</span> <span class="bp">|</span><span class="n">a</span><span class="bp">|</span> <span class="bp">+</span> <span class="mi">1</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">exists_abs_le_of_convergesTo</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">cs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">|</span><span class="n">s</span><span class="w"> </span><span class="n">n</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">cs</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">zero_lt_one</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="n">h</span><span class="o">⟩</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="bp">|</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>In fact, the theorem could be strengthened to assert
-
@@ -1751,31 +1752,31 @@ To do so, we use the previous theorem to find a <code class="docutils literal notranslate"><span class="pre">B</span></code>that bounds <code class="docutils literal notranslate"><span class="pre">s</span></code> beyond some point <code class="docutils literal notranslate"><span class="pre">N₀</span></code>. See if you can understand the strategy we have outlined and finish the proof.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">aux</span> <span class="o">{</span><span class="n">s</span> <span class="n">t</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">{</span><span class="n">a</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">cs</span> <span class="o">:</span> <span class="n">ConvergesTo</span> <span class="n">s</span> <span class="n">a</span><span class="o">)</span> <span class="o">(</span><span class="n">ct</span> <span class="o">:</span> <span class="n">ConvergesTo</span> <span class="n">t</span> <span class="mi">0</span><span class="o">)</span> <span class="o">:</span> <span class="n">ConvergesTo</span> <span class="o">(</span><span class="k">fun</span> <span class="n">n</span> <span class="bp">↦</span> <span class="n">s</span> <span class="n">n</span> <span class="bp">*</span> <span class="n">t</span> <span class="n">n</span><span class="o">)</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">ε</span> <span class="n">εpos</span> <span class="n">dsimp</span> <span class="n">rcases</span> <span class="n">exists_abs_le_of_convergesTo</span> <span class="n">cs</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">N₀</span><span class="o">,</span> <span class="n">B</span><span class="o">,</span> <span class="n">h₀</span><span class="o">⟩</span> <span class="k">have</span> <span class="n">Bpos</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">B</span> <span class="o">:=</span> <span class="n">lt_of_le_of_lt</span> <span class="o">(</span><span class="n">abs_nonneg</span> <span class="n">_</span><span class="o">)</span> <span class="o">(</span><span class="n">h₀</span> <span class="n">N₀</span> <span class="o">(</span><span class="n">le_refl</span> <span class="n">_</span><span class="o">))</span> <span class="k">have</span> <span class="n">pos₀</span> <span class="o">:</span> <span class="n">ε</span> <span class="bp">/</span> <span class="n">B</span> <span class="bp">></span> <span class="mi">0</span> <span class="o">:=</span> <span class="n">div_pos</span> <span class="n">εpos</span> <span class="n">Bpos</span> <span class="n">rcases</span> <span class="n">ct</span> <span class="n">_</span> <span class="n">pos₀</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">N₁</span><span class="o">,</span> <span class="n">h₁</span><span class="o">⟩</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">aux</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">cs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ct</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="n">εpos</span> <span class="w"> </span><span class="n">dsimp</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">exists_abs_le_of_convergesTo</span><span class="w"> </span><span class="n">cs</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">N₀</span><span class="o">,</span><span class="w"> </span><span class="n">B</span><span class="o">,</span><span class="w"> </span><span class="n">h₀</span><span class="o">⟩</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">Bpos</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">lt_of_le_of_lt</span><span class="w"> </span><span class="o">(</span><span class="n">abs_nonneg</span><span class="w"> </span><span class="n">_</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="n">N₀</span><span class="w"> </span><span class="o">(</span><span class="n">le_refl</span><span class="w"> </span><span class="n">_</span><span class="o">))</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">pos₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">div_pos</span><span class="w"> </span><span class="n">εpos</span><span class="w"> </span><span class="n">Bpos</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">ct</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">pos₀</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">N₁</span><span class="o">,</span><span class="w"> </span><span class="n">h₁</span><span class="o">⟩</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>If you have made it this far, congratulations! We are now within striking distance of our theorem. The following proof finishes it off.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">convergesTo_mul</span> <span class="o">{</span><span class="n">s</span> <span class="n">t</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">cs</span> <span class="o">:</span> <span class="n">ConvergesTo</span> <span class="n">s</span> <span class="n">a</span><span class="o">)</span> <span class="o">(</span><span class="n">ct</span> <span class="o">:</span> <span class="n">ConvergesTo</span> <span class="n">t</span> <span class="n">b</span><span class="o">)</span> <span class="o">:</span> <span class="n">ConvergesTo</span> <span class="o">(</span><span class="k">fun</span> <span class="n">n</span> <span class="bp">↦</span> <span class="n">s</span> <span class="n">n</span> <span class="bp">*</span> <span class="n">t</span> <span class="n">n</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">b</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="k">have</span> <span class="n">h₁</span> <span class="o">:</span> <span class="n">ConvergesTo</span> <span class="o">(</span><span class="k">fun</span> <span class="n">n</span> <span class="bp">↦</span> <span class="n">s</span> <span class="n">n</span> <span class="bp">*</span> <span class="o">(</span><span class="n">t</span> <span class="n">n</span> <span class="bp">+</span> <span class="bp">-</span><span class="n">b</span><span class="o">))</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">aux</span> <span class="n">cs</span> <span class="n">convert</span> <span class="n">convergesTo_add</span> <span class="n">ct</span> <span class="o">(</span><span class="n">convergesTo_const</span> <span class="o">(</span><span class="bp">-</span><span class="n">b</span><span class="o">))</span> <span class="n">ring</span> <span class="k">have</span> <span class="o">:=</span> <span class="n">convergesTo_add</span> <span class="n">h₁</span> <span class="o">(</span><span class="n">convergesTo_mul_const</span> <span class="n">b</span> <span class="n">cs</span><span class="o">)</span> <span class="n">convert</span> <span class="n">convergesTo_add</span> <span class="n">h₁</span> <span class="o">(</span><span class="n">convergesTo_mul_const</span> <span class="n">b</span> <span class="n">cs</span><span class="o">)</span> <span class="n">using</span> <span class="mi">1</span> <span class="bp">·</span> <span class="n">ext</span><span class="bp">;</span> <span class="n">ring</span> <span class="n">ring</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">convergesTo_mul</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span> <span class="w"> </span><span class="o">(</span><span class="n">cs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ct</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">t</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="bp">-</span><span class="n">b</span><span class="o">))</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">aux</span><span class="w"> </span><span class="n">cs</span> <span class="w"> </span><span class="n">convert</span><span class="w"> </span><span class="n">convergesTo_add</span><span class="w"> </span><span class="n">ct</span><span class="w"> </span><span class="o">(</span><span class="n">convergesTo_const</span><span class="w"> </span><span class="o">(</span><span class="bp">-</span><span class="n">b</span><span class="o">))</span> <span class="w"> </span><span class="n">ring</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">convergesTo_add</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="o">(</span><span class="n">convergesTo_mul_const</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">cs</span><span class="o">)</span> <span class="w"> </span><span class="n">convert</span><span class="w"> </span><span class="n">convergesTo_add</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="o">(</span><span class="n">convergesTo_mul_const</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">cs</span><span class="o">)</span><span class="w"> </span><span class="n">using</span><span class="w"> </span><span class="mi">1</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">ext</span><span class="bp">;</span><span class="w"> </span><span class="n">ring</span> <span class="w"> </span><span class="n">ring</span> </pre></div> </div> <p>For another challenging exercise,
-
@@ -1783,22 +1784,22 @@ try filling out the following sketch of a proof that limitsare unique. (If you are feeling bold, you can delete the proof sketch and try proving it from scratch.)</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">convergesTo_unique</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">sa</span> <span class="o">:</span> <span class="n">ConvergesTo</span> <span class="n">s</span> <span class="n">a</span><span class="o">)</span> <span class="o">(</span><span class="n">sb</span> <span class="o">:</span> <span class="n">ConvergesTo</span> <span class="n">s</span> <span class="n">b</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">=</span> <span class="n">b</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">by_contra</span> <span class="n">abne</span> <span class="k">have</span> <span class="o">:</span> <span class="bp">|</span><span class="n">a</span> <span class="bp">-</span> <span class="n">b</span><span class="bp">|</span> <span class="bp">></span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">let</span> <span class="n">ε</span> <span class="o">:=</span> <span class="bp">|</span><span class="n">a</span> <span class="bp">-</span> <span class="n">b</span><span class="bp">|</span> <span class="bp">/</span> <span class="mi">2</span> <span class="k">have</span> <span class="n">εpos</span> <span class="o">:</span> <span class="n">ε</span> <span class="bp">></span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">change</span> <span class="bp">|</span><span class="n">a</span> <span class="bp">-</span> <span class="n">b</span><span class="bp">|</span> <span class="bp">/</span> <span class="mi">2</span> <span class="bp">></span> <span class="mi">0</span> <span class="n">linarith</span> <span class="n">rcases</span> <span class="n">sa</span> <span class="n">ε</span> <span class="n">εpos</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">Na</span><span class="o">,</span> <span class="n">hNa</span><span class="o">⟩</span> <span class="n">rcases</span> <span class="n">sb</span> <span class="n">ε</span> <span class="n">εpos</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">Nb</span><span class="o">,</span> <span class="n">hNb</span><span class="o">⟩</span> <span class="k">let</span> <span class="n">N</span> <span class="o">:=</span> <span class="n">max</span> <span class="n">Na</span> <span class="n">Nb</span> <span class="k">have</span> <span class="n">absa</span> <span class="o">:</span> <span class="bp">|</span><span class="n">s</span> <span class="n">N</span> <span class="bp">-</span> <span class="n">a</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">ε</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="n">absb</span> <span class="o">:</span> <span class="bp">|</span><span class="n">s</span> <span class="n">N</span> <span class="bp">-</span> <span class="n">b</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">ε</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="o">:</span> <span class="bp">|</span><span class="n">a</span> <span class="bp">-</span> <span class="n">b</span><span class="bp">|</span> <span class="bp"><</span> <span class="bp">|</span><span class="n">a</span> <span class="bp">-</span> <span class="n">b</span><span class="bp">|</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="n">exact</span> <span class="n">lt_irrefl</span> <span class="n">_</span> <span class="n">this</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">convergesTo_unique</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span> <span class="w"> </span><span class="o">(</span><span class="n">sa</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">sb</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ConvergesTo</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">by_contra</span><span class="w"> </span><span class="n">abne</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">let</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">εpos</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">change</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span> <span class="w"> </span><span class="n">linarith</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">sa</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="n">εpos</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">Na</span><span class="o">,</span><span class="w"> </span><span class="n">hNa</span><span class="o">⟩</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">sb</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="n">εpos</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">Nb</span><span class="o">,</span><span class="w"> </span><span class="n">hNb</span><span class="o">⟩</span> <span class="w"> </span><span class="k">let</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">max</span><span class="w"> </span><span class="n">Na</span><span class="w"> </span><span class="n">Nb</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">absa</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">s</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">a</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">absb</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">s</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">lt_irrefl</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">this</span> </pre></div> </div> <p>We close the section with the observation that our proofs can be generalized.
-
@@ -1807,10 +1808,10 @@ natural numbers is that their structure carries a partial orderwith <code class="docutils literal notranslate"><span class="pre">min</span></code> and <code class="docutils literal notranslate"><span class="pre">max</span></code>. You can check that everything still works if you replace <code class="docutils literal notranslate"><span class="pre">ℕ</span></code> everywhere by any linear order <code class="docutils literal notranslate"><span class="pre">α</span></code>:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">LinearOrder</span> <span class="n">α</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">LinearOrder</span><span class="w"> </span><span class="n">α</span><span class="o">]</span> <span class="kd">def</span> <span class="n">ConvergesTo'</span> <span class="o">(</span><span class="n">s</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:=</span> <span class="bp">∀</span> <span class="n">ε</span> <span class="bp">></span> <span class="mi">0</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">N</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">n</span> <span class="bp">≥</span> <span class="n">N</span><span class="o">,</span> <span class="bp">|</span><span class="n">s</span> <span class="n">n</span> <span class="bp">-</span> <span class="n">a</span><span class="bp">|</span> <span class="bp"><</span> <span class="n">ε</span> <span class="kd">def</span><span class="w"> </span><span class="n">ConvergesTo'</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="bp">|</span><span class="n">s</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">a</span><span class="bp">|</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span> </pre></div> </div> <p>In <a class="reference internal" href="C10_Topology.html#filters"><span class="std std-numref">Section 10.1</span></a>, we will see that Mathlib has mechanisms
-
-
-
@@ -1,3 +1,5 @@<!DOCTYPE html> <html class="writer-html5" lang="en" data-content_root="./"> <head>
-
@@ -6,18 +8,17 @@<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>4. Sets and Functions — Mathematics in Lean 0.1 documentation</title> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=80d5e7a1" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=86f27845" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" /> <link rel="stylesheet" type="text/css" href="_static/css/custom.css?v=0731ccc3" /> <link rel="shortcut icon" href="_static/favicon.ico"/> <script src="_static/jquery.js?v=8dae8fb0"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=888ff710"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> <script src="_static/jquery.js?v=5d32c60e"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=9bcbadda"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> <script src="_static/js/theme.js"></script> <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" />
-
@@ -154,69 +155,69 @@ Unlike <code class="docutils literal notranslate"><span class="pre">rw</span></code>, <code class="docutils literal notranslate"><span class="pre">simp</span></code> can perform simplificationsinside a universal or existential quantifier. If you step through the proof, you can see the effects of these commands.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">s</span> <span class="n">t</span> <span class="n">u</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">α</span><span class="o">)</span> <span class="kn">open</span> <span class="n">Set</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">)</span> <span class="kn">open</span><span class="w"> </span><span class="n">Set</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">⊆</span> <span class="n">t</span><span class="o">)</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">u</span> <span class="bp">⊆</span> <span class="n">t</span> <span class="bp">∩</span> <span class="n">u</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">subset_def</span><span class="o">,</span> <span class="n">inter_def</span><span class="o">,</span> <span class="n">inter_def</span><span class="o">]</span> <span class="n">rw</span> <span class="o">[</span><span class="n">subset_def</span><span class="o">]</span> <span class="n">at</span> <span class="n">h</span> <span class="n">simp</span> <span class="n">only</span> <span class="o">[</span><span class="n">mem_setOf</span><span class="o">]</span> <span class="n">rintro</span> <span class="n">x</span> <span class="o">⟨</span><span class="n">xs</span><span class="o">,</span> <span class="n">xu</span><span class="o">⟩</span> <span class="n">exact</span> <span class="o">⟨</span><span class="n">h</span> <span class="n">_</span> <span class="n">xs</span><span class="o">,</span> <span class="n">xu</span><span class="o">⟩</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">subset_def</span><span class="o">,</span><span class="w"> </span><span class="n">inter_def</span><span class="o">,</span><span class="w"> </span><span class="n">inter_def</span><span class="o">]</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">subset_def</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="n">only</span><span class="w"> </span><span class="o">[</span><span class="n">mem_setOf</span><span class="o">]</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">⟨</span><span class="n">xs</span><span class="o">,</span><span class="w"> </span><span class="n">xu</span><span class="o">⟩</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">h</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">xs</span><span class="o">,</span><span class="w"> </span><span class="n">xu</span><span class="o">⟩</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">⊆</span> <span class="n">t</span><span class="o">)</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">u</span> <span class="bp">⊆</span> <span class="n">t</span> <span class="bp">∩</span> <span class="n">u</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="n">only</span> <span class="o">[</span><span class="n">subset_def</span><span class="o">,</span> <span class="n">mem_inter_iff</span><span class="o">]</span> <span class="n">at</span> <span class="bp">*</span> <span class="n">rintro</span> <span class="n">x</span> <span class="o">⟨</span><span class="n">xs</span><span class="o">,</span> <span class="n">xu</span><span class="o">⟩</span> <span class="n">exact</span> <span class="o">⟨</span><span class="n">h</span> <span class="n">_</span> <span class="n">xs</span><span class="o">,</span> <span class="n">xu</span><span class="o">⟩</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="n">only</span><span class="w"> </span><span class="o">[</span><span class="n">subset_def</span><span class="o">,</span><span class="w"> </span><span class="n">mem_inter_iff</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="bp">*</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">⟨</span><span class="n">xs</span><span class="o">,</span><span class="w"> </span><span class="n">xu</span><span class="o">⟩</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">h</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">xs</span><span class="o">,</span><span class="w"> </span><span class="n">xu</span><span class="o">⟩</span> </pre></div> </div> <p>In this example, we open the <code class="docutils literal notranslate"><span class="pre">set</span></code> namespace to have access to the shorter names for the theorems. But, in fact, we can delete the calls to <code class="docutils literal notranslate"><span class="pre">rw</span></code> and <code class="docutils literal notranslate"><span class="pre">simp</span></code> entirely:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">⊆</span> <span class="n">t</span><span class="o">)</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">u</span> <span class="bp">⊆</span> <span class="n">t</span> <span class="bp">∩</span> <span class="n">u</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">x</span> <span class="n">xsu</span> <span class="n">exact</span> <span class="o">⟨</span><span class="n">h</span> <span class="n">xsu.1</span><span class="o">,</span> <span class="n">xsu.2</span><span class="o">⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">xsu</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">h</span><span class="w"> </span><span class="n">xsu</span><span class="bp">.</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="n">xsu</span><span class="bp">.</span><span class="mi">2</span><span class="o">⟩</span> </pre></div> </div> <p>What is going on here is known as <em>definitional reduction</em>: to make sense of the <code class="docutils literal notranslate"><span class="pre">intro</span></code> command and the anonymous constructors Lean is forced to expand the definitions. The following example also illustrate the phenomenon:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">⊆</span> <span class="n">t</span><span class="o">)</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">u</span> <span class="bp">⊆</span> <span class="n">t</span> <span class="bp">∩</span> <span class="n">u</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">x</span> <span class="o">⟨</span><span class="n">xs</span><span class="o">,</span> <span class="n">xu</span><span class="o">⟩</span> <span class="bp">↦</span> <span class="o">⟨</span><span class="n">h</span> <span class="n">xs</span><span class="o">,</span> <span class="n">xu</span><span class="o">⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">⟨</span><span class="n">xs</span><span class="o">,</span><span class="w"> </span><span class="n">xu</span><span class="o">⟩</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">⟨</span><span class="n">h</span><span class="w"> </span><span class="n">xs</span><span class="o">,</span><span class="w"> </span><span class="n">xu</span><span class="o">⟩</span> </pre></div> </div> <p>To deal with unions, we can use <code class="docutils literal notranslate"><span class="pre">Set.union_def</span></code> and <code class="docutils literal notranslate"><span class="pre">Set.mem_union</span></code>. Since <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">∈</span> <span class="pre">s</span> <span class="pre">∪</span> <span class="pre">t</span></code> unfolds to <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">∈</span> <span class="pre">s</span> <span class="pre">∨</span> <span class="pre">x</span> <span class="pre">∈</span> <span class="pre">t</span></code>, we can also use the <code class="docutils literal notranslate"><span class="pre">cases</span></code> tactic to force a definitional reduction.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">∩</span> <span class="o">(</span><span class="n">t</span> <span class="bp">∪</span> <span class="n">u</span><span class="o">)</span> <span class="bp">⊆</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">t</span> <span class="bp">∪</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">u</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">x</span> <span class="n">hx</span> <span class="k">have</span> <span class="n">xs</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">s</span> <span class="o">:=</span> <span class="n">hx.1</span> <span class="k">have</span> <span class="n">xtu</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">t</span> <span class="bp">∪</span> <span class="n">u</span> <span class="o">:=</span> <span class="n">hx.2</span> <span class="n">rcases</span> <span class="n">xtu</span> <span class="k">with</span> <span class="n">xt</span> <span class="bp">|</span> <span class="n">xu</span> <span class="bp">·</span> <span class="n">left</span> <span class="k">show</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">t</span> <span class="n">exact</span> <span class="o">⟨</span><span class="n">xs</span><span class="o">,</span> <span class="n">xt</span><span class="o">⟩</span> <span class="bp">·</span> <span class="n">right</span> <span class="k">show</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">u</span> <span class="n">exact</span> <span class="o">⟨</span><span class="n">xs</span><span class="o">,</span> <span class="n">xu</span><span class="o">⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="o">(</span><span class="n">t</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">u</span><span class="o">)</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">hx</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">xs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">hx</span><span class="bp">.</span><span class="mi">1</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">xtu</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">hx</span><span class="bp">.</span><span class="mi">2</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">xtu</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">xt</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">xu</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">left</span> <span class="w"> </span><span class="k">show</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">t</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">xs</span><span class="o">,</span><span class="w"> </span><span class="n">xt</span><span class="o">⟩</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">right</span> <span class="w"> </span><span class="k">show</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">u</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">xs</span><span class="o">,</span><span class="w"> </span><span class="n">xu</span><span class="o">⟩</span> </pre></div> </div> <p>Since intersection binds tighter than union, the use of parentheses in the expression <code class="docutils literal notranslate"><span class="pre">(s</span> <span class="pre">∩</span> <span class="pre">t)</span> <span class="pre">∪</span> <span class="pre">(s</span> <span class="pre">∩</span> <span class="pre">u)</span></code> is unnecessary, but they make the meaning of the expression clearer. The following is a shorter proof of the same fact:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">∩</span> <span class="o">(</span><span class="n">t</span> <span class="bp">∪</span> <span class="n">u</span><span class="o">)</span> <span class="bp">⊆</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">t</span> <span class="bp">∪</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">u</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rintro</span> <span class="n">x</span> <span class="o">⟨</span><span class="n">xs</span><span class="o">,</span> <span class="n">xt</span> <span class="bp">|</span> <span class="n">xu</span><span class="o">⟩</span> <span class="bp">·</span> <span class="n">left</span><span class="bp">;</span> <span class="n">exact</span> <span class="o">⟨</span><span class="n">xs</span><span class="o">,</span> <span class="n">xt</span><span class="o">⟩</span> <span class="bp">·</span> <span class="n">right</span><span class="bp">;</span> <span class="n">exact</span> <span class="o">⟨</span><span class="n">xs</span><span class="o">,</span> <span class="n">xu</span><span class="o">⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="o">(</span><span class="n">t</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">u</span><span class="o">)</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">⟨</span><span class="n">xs</span><span class="o">,</span><span class="w"> </span><span class="n">xt</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">xu</span><span class="o">⟩</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">left</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">xs</span><span class="o">,</span><span class="w"> </span><span class="n">xt</span><span class="o">⟩</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">right</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">xs</span><span class="o">,</span><span class="w"> </span><span class="n">xu</span><span class="o">⟩</span> </pre></div> </div> <p>As an exercise, try proving the other inclusion:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">t</span> <span class="bp">∪</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">u</span> <span class="bp">⊆</span> <span class="n">s</span> <span class="bp">∩</span> <span class="o">(</span><span class="n">t</span> <span class="bp">∪</span> <span class="n">u</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="o">(</span><span class="n">t</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">u</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>It might help to know that when using <code class="docutils literal notranslate"><span class="pre">rintro</span></code>,
-
@@ -231,28 +232,28 @@ It can be rewritten manually using <code class="docutils literal notranslate"><span class="pre">Set.diff_eq</span></code> and <code class="docutils literal notranslate"><span class="pre">dsimp</span></code>or <code class="docutils literal notranslate"><span class="pre">Set.mem_diff</span></code>, but the following two proofs of the same inclusion show how to avoid using them.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">s</span> <span class="bp">\</span> <span class="n">t</span><span class="o">)</span> <span class="bp">\</span> <span class="n">u</span> <span class="bp">⊆</span> <span class="n">s</span> <span class="bp">\</span> <span class="o">(</span><span class="n">t</span> <span class="bp">∪</span> <span class="n">u</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">x</span> <span class="n">xstu</span> <span class="k">have</span> <span class="n">xs</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">s</span> <span class="o">:=</span> <span class="n">xstu.1.1</span> <span class="k">have</span> <span class="n">xnt</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∉</span> <span class="n">t</span> <span class="o">:=</span> <span class="n">xstu.1.2</span> <span class="k">have</span> <span class="n">xnu</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∉</span> <span class="n">u</span> <span class="o">:=</span> <span class="n">xstu.2</span> <span class="n">constructor</span> <span class="bp">·</span> <span class="n">exact</span> <span class="n">xs</span> <span class="n">intro</span> <span class="n">xtu</span> <span class="c1">-- x ∈ t ∨ x ∈ u</span> <span class="n">rcases</span> <span class="n">xtu</span> <span class="k">with</span> <span class="n">xt</span> <span class="bp">|</span> <span class="n">xu</span> <span class="bp">·</span> <span class="k">show</span> <span class="n">False</span><span class="bp">;</span> <span class="n">exact</span> <span class="n">xnt</span> <span class="n">xt</span> <span class="bp">·</span> <span class="k">show</span> <span class="n">False</span><span class="bp">;</span> <span class="n">exact</span> <span class="n">xnu</span> <span class="n">xu</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="bp">\</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="bp">\</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">\</span><span class="w"> </span><span class="o">(</span><span class="n">t</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">u</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">xstu</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">xs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">xstu</span><span class="bp">.</span><span class="mi">1</span><span class="bp">.</span><span class="mi">1</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">xnt</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∉</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">xstu</span><span class="bp">.</span><span class="mi">1</span><span class="bp">.</span><span class="mi">2</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">xnu</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∉</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">xstu</span><span class="bp">.</span><span class="mi">2</span> <span class="w"> </span><span class="n">constructor</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">xs</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">xtu</span> <span class="w"> </span><span class="c1">-- x ∈ t ∨ x ∈ u</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">xtu</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">xt</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">xu</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="k">show</span><span class="w"> </span><span class="n">False</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">xnt</span><span class="w"> </span><span class="n">xt</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="k">show</span><span class="w"> </span><span class="n">False</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">xnu</span><span class="w"> </span><span class="n">xu</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">s</span> <span class="bp">\</span> <span class="n">t</span><span class="o">)</span> <span class="bp">\</span> <span class="n">u</span> <span class="bp">⊆</span> <span class="n">s</span> <span class="bp">\</span> <span class="o">(</span><span class="n">t</span> <span class="bp">∪</span> <span class="n">u</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rintro</span> <span class="n">x</span> <span class="o">⟨⟨</span><span class="n">xs</span><span class="o">,</span> <span class="n">xnt</span><span class="o">⟩,</span> <span class="n">xnu</span><span class="o">⟩</span> <span class="n">use</span> <span class="n">xs</span> <span class="n">rintro</span> <span class="o">(</span><span class="n">xt</span> <span class="bp">|</span> <span class="n">xu</span><span class="o">)</span> <span class="bp"><;></span> <span class="n">contradiction</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="bp">\</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="bp">\</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">\</span><span class="w"> </span><span class="o">(</span><span class="n">t</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">u</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">⟨⟨</span><span class="n">xs</span><span class="o">,</span><span class="w"> </span><span class="n">xnt</span><span class="o">⟩,</span><span class="w"> </span><span class="n">xnu</span><span class="o">⟩</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">xs</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="o">(</span><span class="n">xt</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">xu</span><span class="o">)</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">contradiction</span> </pre></div> </div> <p>As an exercise, prove the reverse inclusion:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">\</span> <span class="o">(</span><span class="n">t</span> <span class="bp">∪</span> <span class="n">u</span><span class="o">)</span> <span class="bp">⊆</span> <span class="o">(</span><span class="n">s</span> <span class="bp">\</span> <span class="n">t</span><span class="o">)</span> <span class="bp">\</span> <span class="n">u</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">\</span><span class="w"> </span><span class="o">(</span><span class="n">t</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">u</span><span class="o">)</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="bp">\</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="bp">\</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>To prove that two sets are equal,
-
@@ -261,57 +262,57 @@ of the other.This principle is known as “extensionality,” and, unsurprisingly, the <code class="docutils literal notranslate"><span class="pre">ext</span></code> tactic is equipped to handle it.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">t</span> <span class="bp">=</span> <span class="n">t</span> <span class="bp">∩</span> <span class="n">s</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ext</span> <span class="n">x</span> <span class="n">simp</span> <span class="n">only</span> <span class="o">[</span><span class="n">mem_inter_iff</span><span class="o">]</span> <span class="n">constructor</span> <span class="bp">·</span> <span class="n">rintro</span> <span class="o">⟨</span><span class="n">xs</span><span class="o">,</span> <span class="n">xt</span><span class="o">⟩</span><span class="bp">;</span> <span class="n">exact</span> <span class="o">⟨</span><span class="n">xt</span><span class="o">,</span> <span class="n">xs</span><span class="o">⟩</span> <span class="bp">·</span> <span class="n">rintro</span> <span class="o">⟨</span><span class="n">xt</span><span class="o">,</span> <span class="n">xs</span><span class="o">⟩</span><span class="bp">;</span> <span class="n">exact</span> <span class="o">⟨</span><span class="n">xs</span><span class="o">,</span> <span class="n">xt</span><span class="o">⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="n">only</span><span class="w"> </span><span class="o">[</span><span class="n">mem_inter_iff</span><span class="o">]</span> <span class="w"> </span><span class="n">constructor</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="o">⟨</span><span class="n">xs</span><span class="o">,</span><span class="w"> </span><span class="n">xt</span><span class="o">⟩</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">xt</span><span class="o">,</span><span class="w"> </span><span class="n">xs</span><span class="o">⟩</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="o">⟨</span><span class="n">xt</span><span class="o">,</span><span class="w"> </span><span class="n">xs</span><span class="o">⟩</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">xs</span><span class="o">,</span><span class="w"> </span><span class="n">xt</span><span class="o">⟩</span> </pre></div> </div> <p>Once again, deleting the line <code class="docutils literal notranslate"><span class="pre">simp</span> <span class="pre">only</span> <span class="pre">[mem_inter_iff]</span></code> does not harm the proof. In fact, if you like inscrutable proof terms, the following one-line proof is for you:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">t</span> <span class="bp">=</span> <span class="n">t</span> <span class="bp">∩</span> <span class="n">s</span> <span class="o">:=</span> <span class="n">Set.ext</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="o">⟨</span><span class="k">fun</span> <span class="o">⟨</span><span class="n">xs</span><span class="o">,</span> <span class="n">xt</span><span class="o">⟩</span> <span class="bp">↦</span> <span class="o">⟨</span><span class="n">xt</span><span class="o">,</span> <span class="n">xs</span><span class="o">⟩,</span> <span class="k">fun</span> <span class="o">⟨</span><span class="n">xt</span><span class="o">,</span> <span class="n">xs</span><span class="o">⟩</span> <span class="bp">↦</span> <span class="o">⟨</span><span class="n">xs</span><span class="o">,</span> <span class="n">xt</span><span class="o">⟩⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Set.ext</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">⟨</span><span class="k">fun</span><span class="w"> </span><span class="o">⟨</span><span class="n">xs</span><span class="o">,</span><span class="w"> </span><span class="n">xt</span><span class="o">⟩</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">⟨</span><span class="n">xt</span><span class="o">,</span><span class="w"> </span><span class="n">xs</span><span class="o">⟩,</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="o">⟨</span><span class="n">xt</span><span class="o">,</span><span class="w"> </span><span class="n">xs</span><span class="o">⟩</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">⟨</span><span class="n">xs</span><span class="o">,</span><span class="w"> </span><span class="n">xt</span><span class="o">⟩⟩</span> </pre></div> </div> <p>Here is an even shorter proof, using the simplifier:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">t</span> <span class="bp">=</span> <span class="n">t</span> <span class="bp">∩</span> <span class="n">s</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ext</span> <span class="n">x</span><span class="bp">;</span> <span class="n">simp</span> <span class="o">[</span><span class="n">and_comm</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="n">x</span><span class="bp">;</span><span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">and_comm</span><span class="o">]</span> </pre></div> </div> <p>An alternative to using <code class="docutils literal notranslate"><span class="pre">ext</span></code> is to use the theorem <code class="docutils literal notranslate"><span class="pre">Subset.antisymm</span></code> which allows us to prove an equation <code class="docutils literal notranslate"><span class="pre">s</span> <span class="pre">=</span> <span class="pre">t</span></code> between sets by proving <code class="docutils literal notranslate"><span class="pre">s</span> <span class="pre">⊆</span> <span class="pre">t</span></code> and <code class="docutils literal notranslate"><span class="pre">t</span> <span class="pre">⊆</span> <span class="pre">s</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">t</span> <span class="bp">=</span> <span class="n">t</span> <span class="bp">∩</span> <span class="n">s</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">Subset.antisymm</span> <span class="bp">·</span> <span class="n">rintro</span> <span class="n">x</span> <span class="o">⟨</span><span class="n">xs</span><span class="o">,</span> <span class="n">xt</span><span class="o">⟩</span><span class="bp">;</span> <span class="n">exact</span> <span class="o">⟨</span><span class="n">xt</span><span class="o">,</span> <span class="n">xs</span><span class="o">⟩</span> <span class="bp">·</span> <span class="n">rintro</span> <span class="n">x</span> <span class="o">⟨</span><span class="n">xt</span><span class="o">,</span> <span class="n">xs</span><span class="o">⟩</span><span class="bp">;</span> <span class="n">exact</span> <span class="o">⟨</span><span class="n">xs</span><span class="o">,</span> <span class="n">xt</span><span class="o">⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">Subset.antisymm</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">⟨</span><span class="n">xs</span><span class="o">,</span><span class="w"> </span><span class="n">xt</span><span class="o">⟩</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">xt</span><span class="o">,</span><span class="w"> </span><span class="n">xs</span><span class="o">⟩</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">⟨</span><span class="n">xt</span><span class="o">,</span><span class="w"> </span><span class="n">xs</span><span class="o">⟩</span><span class="bp">;</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">xs</span><span class="o">,</span><span class="w"> </span><span class="n">xt</span><span class="o">⟩</span> </pre></div> </div> <p>Try finishing this proof term:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">t</span> <span class="bp">=</span> <span class="n">t</span> <span class="bp">∩</span> <span class="n">s</span> <span class="o">:=</span> <span class="n">Subset.antisymm</span> <span class="gr">sorry</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Subset.antisymm</span><span class="w"> </span><span class="gr">sorry</span><span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Remember that you can replace <cite>sorry</cite> by an underscore, and when you hover over it, Lean will show you what it expects at that point.</p> <p>Here are some set-theoretic identities you might enjoy proving:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">∩</span> <span class="o">(</span><span class="n">s</span> <span class="bp">∪</span> <span class="n">t</span><span class="o">)</span> <span class="bp">=</span> <span class="n">s</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">∪</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">t</span> <span class="bp">=</span> <span class="n">s</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">\</span> <span class="n">t</span> <span class="bp">∪</span> <span class="n">t</span> <span class="bp">=</span> <span class="n">s</span> <span class="bp">∪</span> <span class="n">t</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">\</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">\</span> <span class="n">t</span> <span class="bp">∪</span> <span class="n">t</span> <span class="bp">\</span> <span class="n">s</span> <span class="bp">=</span> <span class="o">(</span><span class="n">s</span> <span class="bp">∪</span> <span class="n">t</span><span class="o">)</span> <span class="bp">\</span> <span class="o">(</span><span class="n">s</span> <span class="bp">∩</span> <span class="n">t</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">\</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">\</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="bp">\</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>When it comes to representing sets,
-
@@ -327,17 +328,17 @@ <p>The library also defines set-builder notation.The expression <code class="docutils literal notranslate"><span class="pre">{</span> <span class="pre">y</span> <span class="pre">|</span> <span class="pre">P</span> <span class="pre">y</span> <span class="pre">}</span></code> unfolds to <code class="docutils literal notranslate"><span class="pre">(fun</span> <span class="pre">y</span> <span class="pre">↦</span> <span class="pre">P</span> <span class="pre">y)</span></code>, so <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">∈</span> <span class="pre">{</span> <span class="pre">y</span> <span class="pre">|</span> <span class="pre">P</span> <span class="pre">y</span> <span class="pre">}</span></code> reduces to <code class="docutils literal notranslate"><span class="pre">P</span> <span class="pre">x</span></code>. So we can turn the property of being even into the set of even numbers:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">evens</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">ℕ</span> <span class="o">:=</span> <span class="o">{</span> <span class="n">n</span> <span class="bp">|</span> <span class="n">Even</span> <span class="n">n</span> <span class="o">}</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">evens</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">Even</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">}</span> <span class="kd">def</span> <span class="n">odds</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">ℕ</span> <span class="o">:=</span> <span class="o">{</span> <span class="n">n</span> <span class="bp">|</span> <span class="bp">¬</span><span class="n">Even</span> <span class="n">n</span> <span class="o">}</span> <span class="kd">def</span><span class="w"> </span><span class="n">odds</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="bp">¬</span><span class="n">Even</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">}</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">evens</span> <span class="bp">∪</span> <span class="n">odds</span> <span class="bp">=</span> <span class="n">univ</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">evens</span><span class="o">,</span> <span class="n">odds</span><span class="o">]</span> <span class="n">ext</span> <span class="n">n</span> <span class="n">simp</span> <span class="o">[</span><span class="bp">-</span><span class="n">Nat.not_even_iff_odd</span><span class="o">]</span> <span class="n">apply</span> <span class="n">Classical.em</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">evens</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">odds</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">univ</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">evens</span><span class="o">,</span><span class="w"> </span><span class="n">odds</span><span class="o">]</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="n">n</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="bp">-</span><span class="n">Nat.not_even_iff_odd</span><span class="o">]</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">Classical.em</span> </pre></div> </div> <p>You should step through this proof and make sure
-
@@ -360,11 +361,11 @@ because Lean has trouble guessing which ones we mean.The following examples show how Lean unfolds the last two definitions when needed. In the second one, <code class="docutils literal notranslate"><span class="pre">trivial</span></code> is the canonical proof of <code class="docutils literal notranslate"><span class="pre">True</span></code> in the library.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∈</span> <span class="o">(</span><span class="bp">∅</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">ℕ</span><span class="o">))</span> <span class="o">:</span> <span class="n">False</span> <span class="o">:=</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="o">(</span><span class="bp">∅</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">ℕ</span><span class="o">))</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">False</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">h</span> <span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∈</span> <span class="o">(</span><span class="n">univ</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:=</span> <span class="n">trivial</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="o">(</span><span class="n">univ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">trivial</span> </pre></div> </div> <p>As an exercise, prove the following inclusion.
-
@@ -373,8 +374,8 @@ and use the simplifier to reduce theset-theoretic constructions to logic. We also recommend using the theorems <code class="docutils literal notranslate"><span class="pre">Nat.Prime.eq_two_or_odd</span></code> and <code class="docutils literal notranslate"><span class="pre">Nat.odd_iff</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="o">{</span> <span class="n">n</span> <span class="bp">|</span> <span class="n">Nat.Prime</span> <span class="n">n</span> <span class="o">}</span> <span class="bp">∩</span> <span class="o">{</span> <span class="n">n</span> <span class="bp">|</span> <span class="n">n</span> <span class="bp">></span> <span class="mi">2</span> <span class="o">}</span> <span class="bp">⊆</span> <span class="o">{</span> <span class="n">n</span> <span class="bp">|</span> <span class="bp">¬</span><span class="n">Even</span> <span class="n">n</span> <span class="o">}</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">Nat.Prime</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">}</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">}</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="bp">¬</span><span class="n">Even</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">}</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Be careful: it is somewhat confusing that the library has multiple versions
-
@@ -383,21 +384,21 @@ The most general one makes sense in any commutative monoid with a zero element.The predicate <code class="docutils literal notranslate"><span class="pre">Nat.Prime</span></code> is specific to the natural numbers. Fortunately, there is a theorem that says that in the specific case, the two notions agree, so you can always rewrite one to the other.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#print</span> <span class="n">Prime</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#print</span><span class="w"> </span><span class="n">Prime</span> <span class="k">#print</span> <span class="n">Nat.Prime</span> <span class="k">#print</span><span class="w"> </span><span class="n">Nat.Prime</span> <span class="kd">example</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:</span> <span class="n">Prime</span> <span class="n">n</span> <span class="bp">↔</span> <span class="n">Nat.Prime</span> <span class="n">n</span> <span class="o">:=</span> <span class="n">Nat.prime_iff.symm</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Prime</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">Nat.Prime</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Nat.prime_iff.symm</span> <span class="kd">example</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">Prime</span> <span class="n">n</span><span class="o">)</span> <span class="o">:</span> <span class="n">Nat.Prime</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">Nat.prime_iff</span><span class="o">]</span> <span class="n">exact</span> <span class="n">h</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Prime</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat.Prime</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">Nat.prime_iff</span><span class="o">]</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p id="index-2">The <cite>rwa</cite> tactic follows a rewrite with the assumption tactic.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">Prime</span> <span class="n">n</span><span class="o">)</span> <span class="o">:</span> <span class="n">Nat.Prime</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rwa</span> <span class="o">[</span><span class="n">Nat.prime_iff</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Prime</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat.Prime</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rwa</span><span class="w"> </span><span class="o">[</span><span class="n">Nat.prime_iff</span><span class="o">]</span> </pre></div> </div> <p id="index-3">Lean introduces the notation <code class="docutils literal notranslate"><span class="pre">∀</span> <span class="pre">x</span> <span class="pre">∈</span> <span class="pre">s,</span> <span class="pre">...</span></code>,
-
@@ -418,28 +419,28 @@ these two expressions behave roughly the same.As a result, we usually don’t need to use <code class="docutils literal notranslate"><span class="pre">bex_def</span></code> to transform them explicitly. Here are some examples of how they are used:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">(</span><span class="n">s</span> <span class="n">t</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">ℕ</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h₀</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="bp">¬</span><span class="n">Even</span> <span class="n">x</span><span class="o">)</span> <span class="o">(</span><span class="n">h₁</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="n">Prime</span> <span class="n">x</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="bp">¬</span><span class="n">Even</span> <span class="n">x</span> <span class="bp">∧</span> <span class="n">Prime</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">x</span> <span class="n">xs</span> <span class="n">constructor</span> <span class="bp">·</span> <span class="n">apply</span> <span class="n">h₀</span> <span class="n">x</span> <span class="n">xs</span> <span class="n">apply</span> <span class="n">h₁</span> <span class="n">x</span> <span class="n">xs</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="bp">¬</span><span class="n">Even</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">Prime</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="bp">¬</span><span class="n">Even</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">Prime</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">xs</span> <span class="w"> </span><span class="n">constructor</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">xs</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">xs</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="bp">¬</span><span class="n">Even</span> <span class="n">x</span> <span class="bp">∧</span> <span class="n">Prime</span> <span class="n">x</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="n">Prime</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rcases</span> <span class="n">h</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">x</span><span class="o">,</span> <span class="n">xs</span><span class="o">,</span> <span class="n">_</span><span class="o">,</span> <span class="n">prime_x</span><span class="o">⟩</span> <span class="n">use</span> <span class="n">x</span><span class="o">,</span> <span class="n">xs</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="bp">¬</span><span class="n">Even</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">Prime</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">Prime</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">xs</span><span class="o">,</span><span class="w"> </span><span class="n">_</span><span class="o">,</span><span class="w"> </span><span class="n">prime_x</span><span class="o">⟩</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">xs</span> </pre></div> </div> <p>See if you can prove these slight variations:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">ssubt</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">⊆</span> <span class="n">t</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">ssubt</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">t</span><span class="o">)</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h₀</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">t</span><span class="o">,</span> <span class="bp">¬</span><span class="n">Even</span> <span class="n">x</span><span class="o">)</span> <span class="o">(</span><span class="n">h₁</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">t</span><span class="o">,</span> <span class="n">Prime</span> <span class="n">x</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="bp">¬</span><span class="n">Even</span> <span class="n">x</span> <span class="bp">∧</span> <span class="n">Prime</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">t</span><span class="o">,</span><span class="w"> </span><span class="bp">¬</span><span class="n">Even</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">t</span><span class="o">,</span><span class="w"> </span><span class="n">Prime</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="bp">¬</span><span class="n">Even</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">Prime</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="bp">¬</span><span class="n">Even</span> <span class="n">x</span> <span class="bp">∧</span> <span class="n">Prime</span> <span class="n">x</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">t</span><span class="o">,</span> <span class="n">Prime</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="bp">¬</span><span class="n">Even</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">Prime</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">t</span><span class="o">,</span><span class="w"> </span><span class="n">Prime</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">end</span> </pre></div>
-
@@ -455,35 +456,35 @@ There is nothing special about the natural numbers here,so <code class="docutils literal notranslate"><span class="pre">ℕ</span></code> can be replaced by any type <code class="docutils literal notranslate"><span class="pre">I</span></code> used to index the sets. The following illustrates their use.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="n">I</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">A</span> <span class="n">B</span> <span class="o">:</span> <span class="n">I</span> <span class="bp">→</span> <span class="n">Set</span> <span class="n">α</span><span class="o">)</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">α</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">A</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">)</span> <span class="kn">open</span> <span class="n">Set</span> <span class="kn">open</span><span class="w"> </span><span class="n">Set</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">s</span> <span class="bp">∩</span> <span class="bp">⋃</span> <span class="n">i</span><span class="o">,</span> <span class="n">A</span> <span class="n">i</span><span class="o">)</span> <span class="bp">=</span> <span class="bp">⋃</span> <span class="n">i</span><span class="o">,</span> <span class="n">A</span> <span class="n">i</span> <span class="bp">∩</span> <span class="n">s</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ext</span> <span class="n">x</span> <span class="n">simp</span> <span class="n">only</span> <span class="o">[</span><span class="n">mem_inter_iff</span><span class="o">,</span> <span class="n">mem_iUnion</span><span class="o">]</span> <span class="n">constructor</span> <span class="bp">·</span> <span class="n">rintro</span> <span class="o">⟨</span><span class="n">xs</span><span class="o">,</span> <span class="o">⟨</span><span class="n">i</span><span class="o">,</span> <span class="n">xAi</span><span class="o">⟩⟩</span> <span class="n">exact</span> <span class="o">⟨</span><span class="n">i</span><span class="o">,</span> <span class="n">xAi</span><span class="o">,</span> <span class="n">xs</span><span class="o">⟩</span> <span class="n">rintro</span> <span class="o">⟨</span><span class="n">i</span><span class="o">,</span> <span class="n">xAi</span><span class="o">,</span> <span class="n">xs</span><span class="o">⟩</span> <span class="n">exact</span> <span class="o">⟨</span><span class="n">xs</span><span class="o">,</span> <span class="o">⟨</span><span class="n">i</span><span class="o">,</span> <span class="n">xAi</span><span class="o">⟩⟩</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="bp">⋃</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">⋃</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="n">only</span><span class="w"> </span><span class="o">[</span><span class="n">mem_inter_iff</span><span class="o">,</span><span class="w"> </span><span class="n">mem_iUnion</span><span class="o">]</span> <span class="w"> </span><span class="n">constructor</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="o">⟨</span><span class="n">xs</span><span class="o">,</span><span class="w"> </span><span class="o">⟨</span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">xAi</span><span class="o">⟩⟩</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">xAi</span><span class="o">,</span><span class="w"> </span><span class="n">xs</span><span class="o">⟩</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="o">⟨</span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">xAi</span><span class="o">,</span><span class="w"> </span><span class="n">xs</span><span class="o">⟩</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">xs</span><span class="o">,</span><span class="w"> </span><span class="o">⟨</span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">xAi</span><span class="o">⟩⟩</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="bp">⋂</span> <span class="n">i</span><span class="o">,</span> <span class="n">A</span> <span class="n">i</span> <span class="bp">∩</span> <span class="n">B</span> <span class="n">i</span><span class="o">)</span> <span class="bp">=</span> <span class="o">(</span><span class="bp">⋂</span> <span class="n">i</span><span class="o">,</span> <span class="n">A</span> <span class="n">i</span><span class="o">)</span> <span class="bp">∩</span> <span class="bp">⋂</span> <span class="n">i</span><span class="o">,</span> <span class="n">B</span> <span class="n">i</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ext</span> <span class="n">x</span> <span class="n">simp</span> <span class="n">only</span> <span class="o">[</span><span class="n">mem_inter_iff</span><span class="o">,</span> <span class="n">mem_iInter</span><span class="o">]</span> <span class="n">constructor</span> <span class="bp">·</span> <span class="n">intro</span> <span class="n">h</span> <span class="n">constructor</span> <span class="bp">·</span> <span class="n">intro</span> <span class="n">i</span> <span class="n">exact</span> <span class="o">(</span><span class="n">h</span> <span class="n">i</span><span class="o">)</span><span class="bp">.</span><span class="mi">1</span> <span class="n">intro</span> <span class="n">i</span> <span class="n">exact</span> <span class="o">(</span><span class="n">h</span> <span class="n">i</span><span class="o">)</span><span class="bp">.</span><span class="mi">2</span> <span class="n">rintro</span> <span class="o">⟨</span><span class="n">h1</span><span class="o">,</span> <span class="n">h2</span><span class="o">⟩</span> <span class="n">i</span> <span class="n">constructor</span> <span class="bp">·</span> <span class="n">exact</span> <span class="n">h1</span> <span class="n">i</span> <span class="n">exact</span> <span class="n">h2</span> <span class="n">i</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">⋂</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="bp">⋂</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="bp">⋂</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="n">only</span><span class="w"> </span><span class="o">[</span><span class="n">mem_inter_iff</span><span class="o">,</span><span class="w"> </span><span class="n">mem_iInter</span><span class="o">]</span> <span class="w"> </span><span class="n">constructor</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">constructor</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">i</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="bp">.</span><span class="mi">1</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">i</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="bp">.</span><span class="mi">2</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="o">⟨</span><span class="n">h1</span><span class="o">,</span><span class="w"> </span><span class="n">h2</span><span class="o">⟩</span><span class="w"> </span><span class="n">i</span> <span class="w"> </span><span class="n">constructor</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h1</span><span class="w"> </span><span class="n">i</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h2</span><span class="w"> </span><span class="n">i</span> </pre></div> </div> <p>Parentheses are often needed with an
-
@@ -494,8 +495,8 @@ <p>Try proving the following identity.One direction requires classical logic! We recommend using <code class="docutils literal notranslate"><span class="pre">by_cases</span> <span class="pre">xs</span> <span class="pre">:</span> <span class="pre">x</span> <span class="pre">∈</span> <span class="pre">s</span></code> at an appropriate point in the proof.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">s</span> <span class="bp">∪</span> <span class="bp">⋂</span> <span class="n">i</span><span class="o">,</span> <span class="n">A</span> <span class="n">i</span><span class="o">)</span> <span class="bp">=</span> <span class="bp">⋂</span> <span class="n">i</span><span class="o">,</span> <span class="n">A</span> <span class="n">i</span> <span class="bp">∪</span> <span class="n">s</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="bp">⋂</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">⋂</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Mathlib also has bounded unions and intersections,
-
@@ -504,23 +505,23 @@ You can unpack their meaning with <code class="docutils literal notranslate"><span class="pre">mem_iUnion₂</span></code>and <code class="docutils literal notranslate"><span class="pre">mem_iInter₂</span></code>. As the following examples show, Lean’s simplifier carries out these replacements as well.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">primes</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">ℕ</span> <span class="o">:=</span> <span class="o">{</span> <span class="n">x</span> <span class="bp">|</span> <span class="n">Nat.Prime</span> <span class="n">x</span> <span class="o">}</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">primes</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">Nat.Prime</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">}</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="bp">⋃</span> <span class="n">p</span> <span class="bp">∈</span> <span class="n">primes</span><span class="o">,</span> <span class="o">{</span> <span class="n">x</span> <span class="bp">|</span> <span class="n">p</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">∣</span> <span class="n">x</span> <span class="o">})</span> <span class="bp">=</span> <span class="o">{</span> <span class="n">x</span> <span class="bp">|</span> <span class="bp">∃</span> <span class="n">p</span> <span class="bp">∈</span> <span class="n">primes</span><span class="o">,</span> <span class="n">p</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">∣</span> <span class="n">x</span> <span class="o">}</span> <span class="o">:=</span><span class="kd">by</span> <span class="n">ext</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mem_iUnion₂</span><span class="o">]</span> <span class="n">simp</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">⋃</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">primes</span><span class="o">,</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">})</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">primes</span><span class="o">,</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">}</span><span class="w"> </span><span class="o">:=</span><span class="kd">by</span> <span class="w"> </span><span class="n">ext</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mem_iUnion₂</span><span class="o">]</span> <span class="w"> </span><span class="n">simp</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="bp">⋃</span> <span class="n">p</span> <span class="bp">∈</span> <span class="n">primes</span><span class="o">,</span> <span class="o">{</span> <span class="n">x</span> <span class="bp">|</span> <span class="n">p</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">∣</span> <span class="n">x</span> <span class="o">})</span> <span class="bp">=</span> <span class="o">{</span> <span class="n">x</span> <span class="bp">|</span> <span class="bp">∃</span> <span class="n">p</span> <span class="bp">∈</span> <span class="n">primes</span><span class="o">,</span> <span class="n">p</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">∣</span> <span class="n">x</span> <span class="o">}</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ext</span> <span class="n">simp</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">⋃</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">primes</span><span class="o">,</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">})</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">primes</span><span class="o">,</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">}</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">ext</span> <span class="w"> </span><span class="n">simp</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="bp">⋂</span> <span class="n">p</span> <span class="bp">∈</span> <span class="n">primes</span><span class="o">,</span> <span class="o">{</span> <span class="n">x</span> <span class="bp">|</span> <span class="bp">¬</span><span class="n">p</span> <span class="bp">∣</span> <span class="n">x</span> <span class="o">})</span> <span class="bp">⊆</span> <span class="o">{</span> <span class="n">x</span> <span class="bp">|</span> <span class="n">x</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">}</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">x</span> <span class="n">contrapose</span><span class="bp">!</span> <span class="n">simp</span> <span class="n">apply</span> <span class="n">Nat.exists_prime_and_dvd</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">⋂</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">primes</span><span class="o">,</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="bp">¬</span><span class="n">p</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">})</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">}</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span> <span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">Nat.exists_prime_and_dvd</span> </pre></div> </div> <p>Try solving the following example, which is similar.
-
@@ -528,8 +529,8 @@ If you start typing <code class="docutils literal notranslate"><span class="pre">eq_univ</span></code>,tab completion will tell you that <code class="docutils literal notranslate"><span class="pre">apply</span> <span class="pre">eq_univ_of_forall</span></code> is a good way to start the proof. We also recommend using the theorem <code class="docutils literal notranslate"><span class="pre">Nat.exists_infinite_primes</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="bp">⋃</span> <span class="n">p</span> <span class="bp">∈</span> <span class="n">primes</span><span class="o">,</span> <span class="o">{</span> <span class="n">x</span> <span class="bp">|</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">p</span> <span class="o">})</span> <span class="bp">=</span> <span class="n">univ</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">⋃</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">primes</span><span class="o">,</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">})</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">univ</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Give a collection of sets, <code class="docutils literal notranslate"><span class="pre">s</span> <span class="pre">:</span> <span class="pre">Set</span> <span class="pre">(Set</span> <span class="pre">α)</span></code>,
-
@@ -540,17 +541,17 @@ <code class="docutils literal notranslate"><span class="pre">{x</span> <span class="pre">|</span> <span class="pre">∀</span> <span class="pre">t</span> <span class="pre">∈</span> <span class="pre">s,</span> <span class="pre">x</span> <span class="pre">∈</span> <span class="pre">t}</span></code>.These operations are called <code class="docutils literal notranslate"><span class="pre">sUnion</span></code> and <code class="docutils literal notranslate"><span class="pre">sInter</span></code>, respectively. The following examples show their relationship to bounded union and intersection.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">(</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="o">(</span><span class="n">Set</span> <span class="n">α</span><span class="o">))</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="o">(</span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">))</span> <span class="kd">example</span> <span class="o">:</span> <span class="bp">⋃₀</span> <span class="n">s</span> <span class="bp">=</span> <span class="bp">⋃</span> <span class="n">t</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="n">t</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ext</span> <span class="n">x</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mem_iUnion₂</span><span class="o">]</span> <span class="n">simp</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">⋃₀</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">⋃</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mem_iUnion₂</span><span class="o">]</span> <span class="w"> </span><span class="n">simp</span> <span class="kd">example</span> <span class="o">:</span> <span class="bp">⋂₀</span> <span class="n">s</span> <span class="bp">=</span> <span class="bp">⋂</span> <span class="n">t</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="n">t</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ext</span> <span class="n">x</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mem_iInter₂</span><span class="o">]</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">⋂₀</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">⋂</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mem_iInter₂</span><span class="o">]</span> <span class="w"> </span><span class="n">rfl</span> </pre></div> </div> <p>In the library, these identities are called
-
@@ -564,17 +565,17 @@ the library defines <code class="docutils literal notranslate"><span class="pre">preimage</span> <span class="pre">f</span> <span class="pre">p</span></code>, written <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">⁻¹'</span> <span class="pre">p</span></code>,to be <code class="docutils literal notranslate"><span class="pre">{x</span> <span class="pre">|</span> <span class="pre">f</span> <span class="pre">x</span> <span class="pre">∈</span> <span class="pre">p}</span></code>. The expression <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">∈</span> <span class="pre">f</span> <span class="pre">⁻¹'</span> <span class="pre">p</span></code> reduces to <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">x</span> <span class="pre">∈</span> <span class="pre">p</span></code>. This is often convenient, as in the following example:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="n">β</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">β</span><span class="o">)</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">s</span> <span class="n">t</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">α</span><span class="o">)</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">u</span> <span class="n">v</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">β</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">β</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">β</span><span class="o">)</span> <span class="kn">open</span> <span class="n">Function</span> <span class="kn">open</span> <span class="n">Set</span> <span class="kn">open</span><span class="w"> </span><span class="n">Function</span> <span class="kn">open</span><span class="w"> </span><span class="n">Set</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="o">(</span><span class="n">u</span> <span class="bp">∩</span> <span class="n">v</span><span class="o">)</span> <span class="bp">=</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="n">u</span> <span class="bp">∩</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="n">v</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ext</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">v</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">ext</span> <span class="w"> </span><span class="n">rfl</span> </pre></div> </div> <p>If <code class="docutils literal notranslate"><span class="pre">s</span></code> is a set of elements of type <code class="docutils literal notranslate"><span class="pre">α</span></code>,
-
@@ -586,25 +587,25 @@ <code class="docutils literal notranslate"><span class="pre">⟨x,</span> <span class="pre">xs,</span> <span class="pre">xeq⟩</span></code> with <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">:</span> <span class="pre">α</span></code> satisfying the hypotheses <code class="docutils literal notranslate"><span class="pre">xs</span> <span class="pre">:</span> <span class="pre">x</span> <span class="pre">∈</span> <span class="pre">s</span></code>and <code class="docutils literal notranslate"><span class="pre">xeq</span> <span class="pre">:</span> <span class="pre">f</span> <span class="pre">x</span> <span class="pre">=</span> <span class="pre">y</span></code>. The <code class="docutils literal notranslate"><span class="pre">rfl</span></code> tag in the <code class="docutils literal notranslate"><span class="pre">rintro</span></code> tactic (see <a class="reference internal" href="C03_Logic.html#the-existential-quantifier"><span class="std std-numref">Section 3.2</span></a>) was made precisely for this sort of situation.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">''</span> <span class="o">(</span><span class="n">s</span> <span class="bp">∪</span> <span class="n">t</span><span class="o">)</span> <span class="bp">=</span> <span class="n">f</span> <span class="bp">''</span> <span class="n">s</span> <span class="bp">∪</span> <span class="n">f</span> <span class="bp">''</span> <span class="n">t</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ext</span> <span class="n">y</span><span class="bp">;</span> <span class="n">constructor</span> <span class="bp">·</span> <span class="n">rintro</span> <span class="o">⟨</span><span class="n">x</span><span class="o">,</span> <span class="n">xs</span> <span class="bp">|</span> <span class="n">xt</span><span class="o">,</span> <span class="n">rfl</span><span class="o">⟩</span> <span class="bp">·</span> <span class="n">left</span> <span class="n">use</span> <span class="n">x</span><span class="o">,</span> <span class="n">xs</span> <span class="n">right</span> <span class="n">use</span> <span class="n">x</span><span class="o">,</span> <span class="n">xt</span> <span class="n">rintro</span> <span class="o">(⟨</span><span class="n">x</span><span class="o">,</span> <span class="n">xs</span><span class="o">,</span> <span class="n">rfl</span><span class="o">⟩</span> <span class="bp">|</span> <span class="o">⟨</span><span class="n">x</span><span class="o">,</span> <span class="n">xt</span><span class="o">,</span> <span class="n">rfl</span><span class="o">⟩)</span> <span class="bp">·</span> <span class="n">use</span> <span class="n">x</span><span class="o">,</span> <span class="n">Or.inl</span> <span class="n">xs</span> <span class="n">use</span> <span class="n">x</span><span class="o">,</span> <span class="n">Or.inr</span> <span class="n">xt</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="n">y</span><span class="bp">;</span><span class="w"> </span><span class="n">constructor</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="o">⟨</span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">xs</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">xt</span><span class="o">,</span><span class="w"> </span><span class="n">rfl</span><span class="o">⟩</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">left</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">xs</span> <span class="w"> </span><span class="n">right</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">xt</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="o">(⟨</span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">xs</span><span class="o">,</span><span class="w"> </span><span class="n">rfl</span><span class="o">⟩</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="o">⟨</span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">xt</span><span class="o">,</span><span class="w"> </span><span class="n">rfl</span><span class="o">⟩)</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">Or.inl</span><span class="w"> </span><span class="n">xs</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">Or.inr</span><span class="w"> </span><span class="n">xt</span> </pre></div> </div> <p>Notice also that the <code class="docutils literal notranslate"><span class="pre">use</span></code> tactic applies <code class="docutils literal notranslate"><span class="pre">rfl</span></code> to close goals when it can.</p> <p>Here is another example:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">⊆</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="o">(</span><span class="n">f</span> <span class="bp">''</span> <span class="n">s</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">x</span> <span class="n">xs</span> <span class="k">show</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">f</span> <span class="bp">''</span> <span class="n">s</span> <span class="n">use</span> <span class="n">x</span><span class="o">,</span> <span class="n">xs</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">xs</span> <span class="w"> </span><span class="k">show</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">s</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">xs</span> </pre></div> </div> <p>We can replace the line <code class="docutils literal notranslate"><span class="pre">use</span> <span class="pre">x,</span> <span class="pre">xs</span></code> by
-
@@ -613,8 +614,8 @@ use a theorem specifically designed for that purpose.But knowing that the image is defined in terms of an existential quantifier is often convenient.</p> <p>The following equivalence is a good exercise:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">''</span> <span class="n">s</span> <span class="bp">⊆</span> <span class="n">v</span> <span class="bp">↔</span> <span class="n">s</span> <span class="bp">⊆</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="n">v</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>It shows that <code class="docutils literal notranslate"><span class="pre">image</span> <span class="pre">f</span></code> and <code class="docutils literal notranslate"><span class="pre">preimage</span> <span class="pre">f</span></code> are
-
@@ -633,47 +634,47 @@ you to enjoy.You don’t have to do all of them at once; do a few of them, and set the rest aside for a rainy day.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">Injective</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="o">(</span><span class="n">f</span> <span class="bp">''</span> <span class="n">s</span><span class="o">)</span> <span class="bp">⊆</span> <span class="n">s</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">''</span> <span class="o">(</span><span class="n">f</span> <span class="bp">⁻¹'</span> <span class="n">u</span><span class="o">)</span> <span class="bp">⊆</span> <span class="n">u</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="n">u</span><span class="o">)</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">Surjective</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="n">u</span> <span class="bp">⊆</span> <span class="n">f</span> <span class="bp">''</span> <span class="o">(</span><span class="n">f</span> <span class="bp">⁻¹'</span> <span class="n">u</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Surjective</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="n">u</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">⊆</span> <span class="n">t</span><span class="o">)</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">''</span> <span class="n">s</span> <span class="bp">⊆</span> <span class="n">f</span> <span class="bp">''</span> <span class="n">t</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">u</span> <span class="bp">⊆</span> <span class="n">v</span><span class="o">)</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="n">u</span> <span class="bp">⊆</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="n">v</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">v</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="o">(</span><span class="n">u</span> <span class="bp">∪</span> <span class="n">v</span><span class="o">)</span> <span class="bp">=</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="n">u</span> <span class="bp">∪</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="n">v</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">v</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">''</span> <span class="o">(</span><span class="n">s</span> <span class="bp">∩</span> <span class="n">t</span><span class="o">)</span> <span class="bp">⊆</span> <span class="n">f</span> <span class="bp">''</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">f</span> <span class="bp">''</span> <span class="n">t</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">Injective</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">''</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">f</span> <span class="bp">''</span> <span class="n">t</span> <span class="bp">⊆</span> <span class="n">f</span> <span class="bp">''</span> <span class="o">(</span><span class="n">s</span> <span class="bp">∩</span> <span class="n">t</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">''</span> <span class="n">s</span> <span class="bp">\</span> <span class="n">f</span> <span class="bp">''</span> <span class="n">t</span> <span class="bp">⊆</span> <span class="n">f</span> <span class="bp">''</span> <span class="o">(</span><span class="n">s</span> <span class="bp">\</span> <span class="n">t</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">\</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="bp">\</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="n">u</span> <span class="bp">\</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="n">v</span> <span class="bp">⊆</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="o">(</span><span class="n">u</span> <span class="bp">\</span> <span class="n">v</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">\</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="bp">\</span><span class="w"> </span><span class="n">v</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">''</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">v</span> <span class="bp">=</span> <span class="n">f</span> <span class="bp">''</span> <span class="o">(</span><span class="n">s</span> <span class="bp">∩</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="n">v</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="n">v</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">''</span> <span class="o">(</span><span class="n">s</span> <span class="bp">∩</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="n">u</span><span class="o">)</span> <span class="bp">⊆</span> <span class="n">f</span> <span class="bp">''</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">u</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="n">u</span><span class="o">)</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="n">u</span> <span class="bp">⊆</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="o">(</span><span class="n">f</span> <span class="bp">''</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">u</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">u</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">∪</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="n">u</span> <span class="bp">⊆</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="o">(</span><span class="n">f</span> <span class="bp">''</span> <span class="n">s</span> <span class="bp">∪</span> <span class="n">u</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">u</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>You can also try your hand at the next group of exercises,
-
@@ -684,29 +685,29 @@ to guarantee that the index set is nonempty.To prove any of these, we recommend using <code class="docutils literal notranslate"><span class="pre">ext</span></code> or <code class="docutils literal notranslate"><span class="pre">intro</span></code> to unfold the meaning of an equation or inclusion between sets, and then calling <code class="docutils literal notranslate"><span class="pre">simp</span></code> to unpack the conditions for membership.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">I</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">(</span><span class="n">A</span> <span class="o">:</span> <span class="n">I</span> <span class="bp">→</span> <span class="n">Set</span> <span class="n">α</span><span class="o">)</span> <span class="o">(</span><span class="n">B</span> <span class="o">:</span> <span class="n">I</span> <span class="bp">→</span> <span class="n">Set</span> <span class="n">β</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">I</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">A</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">B</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">β</span><span class="o">)</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">f</span> <span class="bp">''</span> <span class="bp">⋃</span> <span class="n">i</span><span class="o">,</span> <span class="n">A</span> <span class="n">i</span><span class="o">)</span> <span class="bp">=</span> <span class="bp">⋃</span> <span class="n">i</span><span class="o">,</span> <span class="n">f</span> <span class="bp">''</span> <span class="n">A</span> <span class="n">i</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="bp">⋃</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">⋃</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">f</span> <span class="bp">''</span> <span class="bp">⋂</span> <span class="n">i</span><span class="o">,</span> <span class="n">A</span> <span class="n">i</span><span class="o">)</span> <span class="bp">⊆</span> <span class="bp">⋂</span> <span class="n">i</span><span class="o">,</span> <span class="n">f</span> <span class="bp">''</span> <span class="n">A</span> <span class="n">i</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="bp">⋂</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="bp">⋂</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">i</span> <span class="o">:</span> <span class="n">I</span><span class="o">)</span> <span class="o">(</span><span class="n">injf</span> <span class="o">:</span> <span class="n">Injective</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="bp">⋂</span> <span class="n">i</span><span class="o">,</span> <span class="n">f</span> <span class="bp">''</span> <span class="n">A</span> <span class="n">i</span><span class="o">)</span> <span class="bp">⊆</span> <span class="n">f</span> <span class="bp">''</span> <span class="bp">⋂</span> <span class="n">i</span><span class="o">,</span> <span class="n">A</span> <span class="n">i</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">i</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">I</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">injf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">⋂</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="bp">⋂</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">f</span> <span class="bp">⁻¹'</span> <span class="bp">⋃</span> <span class="n">i</span><span class="o">,</span> <span class="n">B</span> <span class="n">i</span><span class="o">)</span> <span class="bp">=</span> <span class="bp">⋃</span> <span class="n">i</span><span class="o">,</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="n">B</span> <span class="n">i</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="bp">⋃</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">⋃</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">f</span> <span class="bp">⁻¹'</span> <span class="bp">⋂</span> <span class="n">i</span><span class="o">,</span> <span class="n">B</span> <span class="n">i</span><span class="o">)</span> <span class="bp">=</span> <span class="bp">⋂</span> <span class="n">i</span><span class="o">,</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="n">B</span> <span class="n">i</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="bp">⋂</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">⋂</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>The library defines a predicate <code class="docutils literal notranslate"><span class="pre">InjOn</span> <span class="pre">f</span> <span class="pre">s</span></code> to say that <code class="docutils literal notranslate"><span class="pre">f</span></code> is injective on <code class="docutils literal notranslate"><span class="pre">s</span></code>. It is defined as follows:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">InjOn</span> <span class="n">f</span> <span class="n">s</span> <span class="bp">↔</span> <span class="bp">∀</span> <span class="n">x₁</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">x₂</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="n">f</span> <span class="n">x₁</span> <span class="bp">=</span> <span class="n">f</span> <span class="n">x₂</span> <span class="bp">→</span> <span class="n">x₁</span> <span class="bp">=</span> <span class="n">x₂</span> <span class="o">:=</span> <span class="n">Iff.refl</span> <span class="n">_</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">InjOn</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x₁</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x₂</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x₁</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x₂</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">x₁</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x₂</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Iff.refl</span><span class="w"> </span><span class="n">_</span> </pre></div> </div> <p>The statement <code class="docutils literal notranslate"><span class="pre">Injective</span> <span class="pre">f</span></code> is provably equivalent
-
@@ -720,39 +721,39 @@ to their full domain,there are often relativized versions that restrict the statements to a subset of the domain type.</p> <p>Here are some examples of <code class="docutils literal notranslate"><span class="pre">InjOn</span></code> and <code class="docutils literal notranslate"><span class="pre">range</span></code> in use:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">Set</span> <span class="n">Real</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">Real</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">InjOn</span> <span class="n">log</span> <span class="o">{</span> <span class="n">x</span> <span class="bp">|</span> <span class="n">x</span> <span class="bp">></span> <span class="mi">0</span> <span class="o">}</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">x</span> <span class="n">xpos</span> <span class="n">y</span> <span class="n">ypos</span> <span class="n">intro</span> <span class="n">e</span> <span class="c1">-- log x = log y</span> <span class="k">calc</span> <span class="n">x</span> <span class="bp">=</span> <span class="n">exp</span> <span class="o">(</span><span class="n">log</span> <span class="n">x</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">exp_log</span> <span class="n">xpos</span><span class="o">]</span> <span class="n">_</span> <span class="bp">=</span> <span class="n">exp</span> <span class="o">(</span><span class="n">log</span> <span class="n">y</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">e</span><span class="o">]</span> <span class="n">_</span> <span class="bp">=</span> <span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">exp_log</span> <span class="n">ypos</span><span class="o">]</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">InjOn</span><span class="w"> </span><span class="n">log</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">}</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">xpos</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">ypos</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">e</span> <span class="w"> </span><span class="c1">-- log x = log y</span> <span class="w"> </span><span class="k">calc</span> <span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="o">(</span><span class="n">log</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">exp_log</span><span class="w"> </span><span class="n">xpos</span><span class="o">]</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="o">(</span><span class="n">log</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">e</span><span class="o">]</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">exp_log</span><span class="w"> </span><span class="n">ypos</span><span class="o">]</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">range</span> <span class="n">exp</span> <span class="bp">=</span> <span class="o">{</span> <span class="n">y</span> <span class="bp">|</span> <span class="n">y</span> <span class="bp">></span> <span class="mi">0</span> <span class="o">}</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ext</span> <span class="n">y</span><span class="bp">;</span> <span class="n">constructor</span> <span class="bp">·</span> <span class="n">rintro</span> <span class="o">⟨</span><span class="n">x</span><span class="o">,</span> <span class="n">rfl</span><span class="o">⟩</span> <span class="n">apply</span> <span class="n">exp_pos</span> <span class="n">intro</span> <span class="n">ypos</span> <span class="n">use</span> <span class="n">log</span> <span class="n">y</span> <span class="n">rw</span> <span class="o">[</span><span class="n">exp_log</span> <span class="n">ypos</span><span class="o">]</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">range</span><span class="w"> </span><span class="n">exp</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">}</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="n">y</span><span class="bp">;</span><span class="w"> </span><span class="n">constructor</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="o">⟨</span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">rfl</span><span class="o">⟩</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">exp_pos</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">ypos</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">log</span><span class="w"> </span><span class="n">y</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">exp_log</span><span class="w"> </span><span class="n">ypos</span><span class="o">]</span> </pre></div> </div> <p>Try proving these:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">InjOn</span> <span class="n">sqrt</span> <span class="o">{</span> <span class="n">x</span> <span class="bp">|</span> <span class="n">x</span> <span class="bp">≥</span> <span class="mi">0</span> <span class="o">}</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">InjOn</span><span class="w"> </span><span class="n">sqrt</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">}</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">InjOn</span> <span class="o">(</span><span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">x</span> <span class="bp">^</span> <span class="mi">2</span><span class="o">)</span> <span class="o">{</span> <span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">|</span> <span class="n">x</span> <span class="bp">≥</span> <span class="mi">0</span> <span class="o">}</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">InjOn</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">}</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">sqrt</span> <span class="bp">''</span> <span class="o">{</span> <span class="n">x</span> <span class="bp">|</span> <span class="n">x</span> <span class="bp">≥</span> <span class="mi">0</span> <span class="o">}</span> <span class="bp">=</span> <span class="o">{</span> <span class="n">y</span> <span class="bp">|</span> <span class="n">y</span> <span class="bp">≥</span> <span class="mi">0</span> <span class="o">}</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">sqrt</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">}</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">}</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">range</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">x</span> <span class="bp">^</span> <span class="mi">2</span><span class="o">)</span> <span class="bp">=</span> <span class="o">{</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">|</span> <span class="n">y</span> <span class="bp">≥</span> <span class="mi">0</span> <span class="o">}</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">range</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">}</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>To define the inverse of a function <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">:</span> <span class="pre">α</span> <span class="pre">→</span> <span class="pre">β</span></code>,
-
@@ -772,16 +773,16 @@ This requires an appeal to the <em>axiom of choice</em>.Lean allows various ways of accessing it; one convenient method is to use the classical <code class="docutils literal notranslate"><span class="pre">choose</span></code> operator, illustrated below.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="n">β</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Inhabited</span> <span class="n">α</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Inhabited</span><span class="w"> </span><span class="n">α</span><span class="o">]</span> <span class="k">#check</span> <span class="o">(</span><span class="n">default</span> <span class="o">:</span> <span class="n">α</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">default</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">P</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="kt">Prop</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span><span class="o">,</span> <span class="n">P</span> <span class="n">x</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">P</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="kt">Prop</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="o">)</span> <span class="k">#check</span> <span class="n">Classical.choose</span> <span class="n">h</span> <span class="k">#check</span><span class="w"> </span><span class="n">Classical.choose</span><span class="w"> </span><span class="n">h</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">P</span> <span class="o">(</span><span class="n">Classical.choose</span> <span class="n">h</span><span class="o">)</span> <span class="o">:=</span> <span class="n">Classical.choose_spec</span> <span class="n">h</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="o">(</span><span class="n">Classical.choose</span><span class="w"> </span><span class="n">h</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Classical.choose_spec</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>Given <code class="docutils literal notranslate"><span class="pre">h</span> <span class="pre">:</span> <span class="pre">∃</span> <span class="pre">x,</span> <span class="pre">P</span> <span class="pre">x</span></code>, the value of <code class="docutils literal notranslate"><span class="pre">Classical.choose</span> <span class="pre">h</span></code>
-
@@ -790,16 +791,16 @@ The theorem <code class="docutils literal notranslate"><span class="pre">Classical.choose_spec</span> <span class="pre">h</span></code> says that <code class="docutils literal notranslate"><span class="pre">Classical.choose</span> <span class="pre">h</span></code>meets this specification.</p> <p>With these in hand, we can define the inverse function as follows:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">noncomputable</span> <span class="kn">section</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">noncomputable</span><span class="w"> </span><span class="kn">section</span> <span class="kn">open</span> <span class="n">Classical</span> <span class="kn">open</span><span class="w"> </span><span class="n">Classical</span> <span class="kd">def</span> <span class="n">inverse</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">β</span><span class="o">)</span> <span class="o">:</span> <span class="n">β</span> <span class="bp">→</span> <span class="n">α</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">y</span> <span class="o">:</span> <span class="n">β</span> <span class="bp">↦</span> <span class="k">if</span> <span class="n">h</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">=</span> <span class="n">y</span> <span class="k">then</span> <span class="n">Classical.choose</span> <span class="n">h</span> <span class="k">else</span> <span class="n">default</span> <span class="kd">def</span><span class="w"> </span><span class="n">inverse</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">β</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="bp">↦</span> <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="k">then</span><span class="w"> </span><span class="n">Classical.choose</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="n">default</span> <span class="kd">theorem</span> <span class="n">inverse_spec</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">β</span><span class="o">}</span> <span class="o">(</span><span class="n">y</span> <span class="o">:</span> <span class="n">β</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">=</span> <span class="n">y</span><span class="o">)</span> <span class="o">:</span> <span class="n">f</span> <span class="o">(</span><span class="n">inverse</span> <span class="n">f</span> <span class="n">y</span><span class="o">)</span> <span class="bp">=</span> <span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">inverse</span><span class="o">,</span> <span class="n">dif_pos</span> <span class="n">h</span><span class="o">]</span> <span class="n">exact</span> <span class="n">Classical.choose_spec</span> <span class="n">h</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">inverse_spec</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">β</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">β</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">inverse</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">inverse</span><span class="o">,</span><span class="w"> </span><span class="n">dif_pos</span><span class="w"> </span><span class="n">h</span><span class="o">]</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">Classical.choose_spec</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>The lines <code class="docutils literal notranslate"><span class="pre">noncomputable</span> <span class="pre">section</span></code> and <code class="docutils literal notranslate"><span class="pre">open</span> <span class="pre">Classical</span></code>
-
@@ -832,15 +833,15 @@ You should be able to prove each of them with about a half-dozenshort lines. If you are looking for an extra challenge, try to condense each proof to a single-line proof term.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">β</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">β</span><span class="o">)</span> <span class="kn">open</span> <span class="n">Function</span> <span class="kn">open</span><span class="w"> </span><span class="n">Function</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">Injective</span> <span class="n">f</span> <span class="bp">↔</span> <span class="n">LeftInverse</span> <span class="o">(</span><span class="n">inverse</span> <span class="n">f</span><span class="o">)</span> <span class="n">f</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">LeftInverse</span><span class="w"> </span><span class="o">(</span><span class="n">inverse</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">Surjective</span> <span class="n">f</span> <span class="bp">↔</span> <span class="n">RightInverse</span> <span class="o">(</span><span class="n">inverse</span> <span class="n">f</span><span class="o">)</span> <span class="n">f</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Surjective</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">RightInverse</span><span class="w"> </span><span class="o">(</span><span class="n">inverse</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>We close this section with a type-theoretic statement of Cantor’s
-
@@ -848,19 +849,19 @@ famous theorem that there is no surjective function from a setto its power set. See if you can understand the proof, and then fill in the two lines that are missing.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">Cantor</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">f</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">Set</span> <span class="n">α</span><span class="o">,</span> <span class="bp">¬</span><span class="n">Surjective</span> <span class="n">f</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">f</span> <span class="n">surjf</span> <span class="k">let</span> <span class="n">S</span> <span class="o">:=</span> <span class="o">{</span> <span class="n">i</span> <span class="bp">|</span> <span class="n">i</span> <span class="bp">∉</span> <span class="n">f</span> <span class="n">i</span> <span class="o">}</span> <span class="n">rcases</span> <span class="n">surjf</span> <span class="n">S</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">j</span><span class="o">,</span> <span class="n">h</span><span class="o">⟩</span> <span class="k">have</span> <span class="n">h₁</span> <span class="o">:</span> <span class="n">j</span> <span class="bp">∉</span> <span class="n">f</span> <span class="n">j</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">h'</span> <span class="k">have</span> <span class="o">:</span> <span class="n">j</span> <span class="bp">∉</span> <span class="n">f</span> <span class="n">j</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rwa</span> <span class="o">[</span><span class="n">h</span><span class="o">]</span> <span class="n">at</span> <span class="n">h'</span> <span class="n">contradiction</span> <span class="k">have</span> <span class="n">h₂</span> <span class="o">:</span> <span class="n">j</span> <span class="bp">∈</span> <span class="n">S</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="n">h₃</span> <span class="o">:</span> <span class="n">j</span> <span class="bp">∉</span> <span class="n">S</span> <span class="gr">sorry</span> <span class="n">contradiction</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">Cantor</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="bp">¬</span><span class="n">Surjective</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">surjf</span> <span class="w"> </span><span class="k">let</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">∉</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">}</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">surjf</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">j</span><span class="o">,</span><span class="w"> </span><span class="n">h</span><span class="o">⟩</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="bp">∉</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h'</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="bp">∉</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">rwa</span><span class="w"> </span><span class="o">[</span><span class="n">h</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">h'</span> <span class="w"> </span><span class="n">contradiction</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h₂</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">S</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h₃</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="bp">∉</span><span class="w"> </span><span class="n">S</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">contradiction</span> </pre></div> </div> </section>
-
@@ -888,19 +889,22 @@ <p>To understand the idea behind the proof, consider the image of the map<span class="math notranslate nohighlight">\(g\)</span> in <span class="math notranslate nohighlight">\(\alpha\)</span>. On that image, the inverse of <span class="math notranslate nohighlight">\(g\)</span> is defined and is a bijection with <span class="math notranslate nohighlight">\(\beta\)</span>.</p> <a class="reference internal image-reference" href="_images/schroeder_bernstein1.png"><img alt="the Schröder Bernstein theorem" class="align-center" src="_images/schroeder_bernstein1.png" style="height: 150px;" /></a> <a class="reference internal image-reference" href="_images/schroeder_bernstein1.png"><img alt="the Schröder Bernstein theorem" class="align-center" src="_images/schroeder_bernstein1.png" style="height: 150px;" /> </a> <p>The problem is that the bijection does not include the shaded region in the diagram, which is nonempty if <span class="math notranslate nohighlight">\(g\)</span> is not surjective. Alternatively, we can use <span class="math notranslate nohighlight">\(f\)</span> to map all of <span class="math notranslate nohighlight">\(\alpha\)</span> to <span class="math notranslate nohighlight">\(\beta\)</span>, but in that case the problem is that if <span class="math notranslate nohighlight">\(f\)</span> is not surjective, it will miss some elements of <span class="math notranslate nohighlight">\(\beta\)</span>.</p> <a class="reference internal image-reference" href="_images/schroeder_bernstein2.png"><img alt="the Schröder Bernstein theorem" class="align-center" src="_images/schroeder_bernstein2.png" style="height: 150px;" /></a> <a class="reference internal image-reference" href="_images/schroeder_bernstein2.png"><img alt="the Schröder Bernstein theorem" class="align-center" src="_images/schroeder_bernstein2.png" style="height: 150px;" /> </a> <p>But now consider the composition <span class="math notranslate nohighlight">\(g \circ f\)</span> from <span class="math notranslate nohighlight">\(\alpha\)</span> to itself. Because the composition is injective, it forms a bijection between <span class="math notranslate nohighlight">\(\alpha\)</span> and its image, yielding a scaled-down copy of <span class="math notranslate nohighlight">\(\alpha\)</span> inside itself.</p> <a class="reference internal image-reference" href="_images/schroeder_bernstein3.png"><img alt="the Schröder Bernstein theorem" class="align-center" src="_images/schroeder_bernstein3.png" style="height: 150px;" /></a> <a class="reference internal image-reference" href="_images/schroeder_bernstein3.png"><img alt="the Schröder Bernstein theorem" class="align-center" src="_images/schroeder_bernstein3.png" style="height: 150px;" /> </a> <p>This composition maps the inner shaded ring to yet another such set, which we can think of as an even smaller concentric shaded ring, and so on.
-
@@ -940,9 +944,9 @@ Formalizing the proof will not only improve our confidence in theresult, but also help us understand it better. Because the proof uses classical logic, we tell Lean that our definitions will generally not be computable.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">noncomputable</span> <span class="kn">section</span> <span class="kn">open</span> <span class="n">Classical</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="n">β</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Nonempty</span> <span class="n">β</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">noncomputable</span><span class="w"> </span><span class="kn">section</span> <span class="kn">open</span><span class="w"> </span><span class="n">Classical</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Nonempty</span><span class="w"> </span><span class="n">β</span><span class="o">]</span> </pre></div> </div> <p>The annotation <code class="docutils literal notranslate"><span class="pre">[Nonempty</span> <span class="pre">β]</span></code> specifies that <code class="docutils literal notranslate"><span class="pre">β</span></code> is nonempty.
-
@@ -958,21 +962,21 @@ in <code class="docutils literal notranslate"><span class="pre">β</span></code> if there is one,and returns an arbitrary element of <code class="docutils literal notranslate"><span class="pre">β</span></code> otherwise. The function <code class="docutils literal notranslate"><span class="pre">invFun</span> <span class="pre">g</span></code> is always a left inverse if <code class="docutils literal notranslate"><span class="pre">g</span></code> is injective and a right inverse if <code class="docutils literal notranslate"><span class="pre">g</span></code> is surjective.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="o">(</span><span class="n">invFun</span> <span class="n">g</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">β</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">leftInverse_invFun</span> <span class="o">:</span> <span class="n">Injective</span> <span class="n">g</span> <span class="bp">→</span> <span class="n">LeftInverse</span> <span class="o">(</span><span class="n">invFun</span> <span class="n">g</span><span class="o">)</span> <span class="n">g</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">leftInverse_invFun</span> <span class="o">:</span> <span class="n">Injective</span> <span class="n">g</span> <span class="bp">→</span> <span class="bp">∀</span> <span class="n">y</span><span class="o">,</span> <span class="n">invFun</span> <span class="n">g</span> <span class="o">(</span><span class="n">g</span> <span class="n">y</span><span class="o">)</span> <span class="bp">=</span> <span class="n">y</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">invFun_eq</span> <span class="o">:</span> <span class="o">(</span><span class="bp">∃</span> <span class="n">y</span><span class="o">,</span> <span class="n">g</span> <span class="n">y</span> <span class="bp">=</span> <span class="n">x</span><span class="o">)</span> <span class="bp">→</span> <span class="n">g</span> <span class="o">(</span><span class="n">invFun</span> <span class="n">g</span> <span class="n">x</span><span class="o">)</span> <span class="bp">=</span> <span class="n">x</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">invFun</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">β</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">leftInverse_invFun</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">LeftInverse</span><span class="w"> </span><span class="o">(</span><span class="n">invFun</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="n">g</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">leftInverse_invFun</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">y</span><span class="o">,</span><span class="w"> </span><span class="n">invFun</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">y</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">invFun_eq</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">∃</span><span class="w"> </span><span class="n">y</span><span class="o">,</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">(</span><span class="n">invFun</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="o">)</span> </pre></div> </div> <p>We define the set corresponding to the union of the shaded regions as follows.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">β</span><span class="o">)</span> <span class="o">(</span><span class="n">g</span> <span class="o">:</span> <span class="n">β</span> <span class="bp">→</span> <span class="n">α</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">β</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span><span class="o">)</span> <span class="kd">def</span> <span class="n">sbAux</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">Set</span> <span class="n">α</span> <span class="bp">|</span> <span class="mi">0</span> <span class="bp">=></span> <span class="n">univ</span> <span class="bp">\</span> <span class="n">g</span> <span class="bp">''</span> <span class="n">univ</span> <span class="bp">|</span> <span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span> <span class="bp">=></span> <span class="n">g</span> <span class="bp">''</span> <span class="o">(</span><span class="n">f</span> <span class="bp">''</span> <span class="n">sbAux</span> <span class="n">n</span><span class="o">)</span> <span class="kd">def</span><span class="w"> </span><span class="n">sbAux</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="n">univ</span><span class="w"> </span><span class="bp">\</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">univ</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">sbAux</span><span class="w"> </span><span class="n">n</span><span class="o">)</span> <span class="kd">def</span> <span class="n">sbSet</span> <span class="o">:=</span> <span class="bp">⋃</span> <span class="n">n</span><span class="o">,</span> <span class="n">sbAux</span> <span class="n">f</span> <span class="n">g</span> <span class="n">n</span> <span class="kd">def</span><span class="w"> </span><span class="n">sbSet</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="bp">⋃</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">sbAux</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">n</span> </pre></div> </div> <p>The definition <code class="docutils literal notranslate"><span class="pre">sbAux</span></code> is an example of a <em>recursive definition</em>,
-
@@ -984,8 +988,8 @@ S_{n+1} &= g(f(S_n)).\end{split}\]</div><p>The definition <code class="docutils literal notranslate"><span class="pre">sbSet</span></code> corresponds to the set <span class="math notranslate nohighlight">\(A = \bigcup_{n \in \mathbb{N}} S_n\)</span> in our proof sketch. The function <span class="math notranslate nohighlight">\(h\)</span> described above is now defined as follows:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">sbFun</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">α</span><span class="o">)</span> <span class="o">:</span> <span class="n">β</span> <span class="o">:=</span> <span class="k">if</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">sbSet</span> <span class="n">f</span> <span class="n">g</span> <span class="k">then</span> <span class="n">f</span> <span class="n">x</span> <span class="k">else</span> <span class="n">invFun</span> <span class="n">g</span> <span class="n">x</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">sbFun</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">sbSet</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="k">then</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="n">invFun</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span> </pre></div> </div> <p>We will need the fact that our definition of <span class="math notranslate nohighlight">\(g^{-1}\)</span> is a
-
@@ -1004,16 +1008,16 @@ and fill in the remaining parts.You will need to use <code class="docutils literal notranslate"><span class="pre">invFun_eq</span></code> at the end. Notice that rewriting with <code class="docutils literal notranslate"><span class="pre">sbAux</span></code> here replaces <code class="docutils literal notranslate"><span class="pre">sbAux</span> <span class="pre">f</span> <span class="pre">g</span> <span class="pre">0</span></code> with the right-hand side of the corresponding defining equation.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">sb_right_inv</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">α</span><span class="o">}</span> <span class="o">(</span><span class="n">hx</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∉</span> <span class="n">sbSet</span> <span class="n">f</span> <span class="n">g</span><span class="o">)</span> <span class="o">:</span> <span class="n">g</span> <span class="o">(</span><span class="n">invFun</span> <span class="n">g</span> <span class="n">x</span><span class="o">)</span> <span class="bp">=</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="k">have</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">g</span> <span class="bp">''</span> <span class="n">univ</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">contrapose</span><span class="bp">!</span> <span class="n">hx</span> <span class="n">rw</span> <span class="o">[</span><span class="n">sbSet</span><span class="o">,</span> <span class="n">mem_iUnion</span><span class="o">]</span> <span class="n">use</span> <span class="mi">0</span> <span class="n">rw</span> <span class="o">[</span><span class="n">sbAux</span><span class="o">,</span> <span class="n">mem_diff</span><span class="o">]</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">y</span><span class="o">,</span> <span class="n">g</span> <span class="n">y</span> <span class="bp">=</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">sb_right_inv</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hx</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∉</span><span class="w"> </span><span class="n">sbSet</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">(</span><span class="n">invFun</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">univ</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span><span class="w"> </span><span class="n">hx</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">sbSet</span><span class="o">,</span><span class="w"> </span><span class="n">mem_iUnion</span><span class="o">]</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="mi">0</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">sbAux</span><span class="o">,</span><span class="w"> </span><span class="n">mem_diff</span><span class="o">]</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">y</span><span class="o">,</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>We now turn to the proof that <span class="math notranslate nohighlight">\(h\)</span> is injective.
-
@@ -1037,32 +1041,32 @@ Applying <span class="math notranslate nohighlight">\(g\)</span> to both sides yields <span class="math notranslate nohighlight">\(x_1 = x_2\)</span>.</p><p>Once again, we encourage you to step through the following proof to see how the argument plays out in Lean. See if you can finish off the proof using <code class="docutils literal notranslate"><span class="pre">sb_right_inv</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">sb_injective</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">Injective</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="n">Injective</span> <span class="o">(</span><span class="n">sbFun</span> <span class="n">f</span> <span class="n">g</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">set</span> <span class="n">A</span> <span class="o">:=</span> <span class="n">sbSet</span> <span class="n">f</span> <span class="n">g</span> <span class="k">with</span> <span class="n">A_def</span> <span class="n">set</span> <span class="n">h</span> <span class="o">:=</span> <span class="n">sbFun</span> <span class="n">f</span> <span class="n">g</span> <span class="k">with</span> <span class="n">h_def</span> <span class="n">intro</span> <span class="n">x₁</span> <span class="n">x₂</span> <span class="n">intro</span> <span class="o">(</span><span class="n">hxeq</span> <span class="o">:</span> <span class="n">h</span> <span class="n">x₁</span> <span class="bp">=</span> <span class="n">h</span> <span class="n">x₂</span><span class="o">)</span> <span class="k">show</span> <span class="n">x₁</span> <span class="bp">=</span> <span class="n">x₂</span> <span class="n">simp</span> <span class="n">only</span> <span class="o">[</span><span class="n">h_def</span><span class="o">,</span> <span class="n">sbFun</span><span class="o">,</span> <span class="bp">←</span> <span class="n">A_def</span><span class="o">]</span> <span class="n">at</span> <span class="n">hxeq</span> <span class="n">by_cases</span> <span class="n">xA</span> <span class="o">:</span> <span class="n">x₁</span> <span class="bp">∈</span> <span class="n">A</span> <span class="bp">∨</span> <span class="n">x₂</span> <span class="bp">∈</span> <span class="n">A</span> <span class="bp">·</span> <span class="n">wlog</span> <span class="n">x₁A</span> <span class="o">:</span> <span class="n">x₁</span> <span class="bp">∈</span> <span class="n">A</span> <span class="n">generalizing</span> <span class="n">x₁</span> <span class="n">x₂</span> <span class="n">hxeq</span> <span class="n">xA</span> <span class="bp">·</span> <span class="n">symm</span> <span class="n">apply</span> <span class="n">this</span> <span class="n">hxeq.symm</span> <span class="n">xA.symm</span> <span class="o">(</span><span class="n">xA.resolve_left</span> <span class="n">x₁A</span><span class="o">)</span> <span class="k">have</span> <span class="n">x₂A</span> <span class="o">:</span> <span class="n">x₂</span> <span class="bp">∈</span> <span class="n">A</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">_root_.not_imp_self.mp</span> <span class="n">intro</span> <span class="o">(</span><span class="n">x₂nA</span> <span class="o">:</span> <span class="n">x₂</span> <span class="bp">∉</span> <span class="n">A</span><span class="o">)</span> <span class="n">rw</span> <span class="o">[</span><span class="n">if_pos</span> <span class="n">x₁A</span><span class="o">,</span> <span class="n">if_neg</span> <span class="n">x₂nA</span><span class="o">]</span> <span class="n">at</span> <span class="n">hxeq</span> <span class="n">rw</span> <span class="o">[</span><span class="n">A_def</span><span class="o">,</span> <span class="n">sbSet</span><span class="o">,</span> <span class="n">mem_iUnion</span><span class="o">]</span> <span class="n">at</span> <span class="n">x₁A</span> <span class="k">have</span> <span class="n">x₂eq</span> <span class="o">:</span> <span class="n">x₂</span> <span class="bp">=</span> <span class="n">g</span> <span class="o">(</span><span class="n">f</span> <span class="n">x₁</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="n">rcases</span> <span class="n">x₁A</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">n</span><span class="o">,</span> <span class="n">hn</span><span class="o">⟩</span> <span class="n">rw</span> <span class="o">[</span><span class="n">A_def</span><span class="o">,</span> <span class="n">sbSet</span><span class="o">,</span> <span class="n">mem_iUnion</span><span class="o">]</span> <span class="n">use</span> <span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span> <span class="n">simp</span> <span class="o">[</span><span class="n">sbAux</span><span class="o">]</span> <span class="n">exact</span> <span class="o">⟨</span><span class="n">x₁</span><span class="o">,</span> <span class="n">hn</span><span class="o">,</span> <span class="n">x₂eq.symm</span><span class="o">⟩</span> <span class="gr">sorry</span> <span class="n">push_neg</span> <span class="n">at</span> <span class="n">xA</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">sb_injective</span><span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="o">(</span><span class="n">sbFun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">set</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">sbSet</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">A_def</span> <span class="w"> </span><span class="n">set</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">sbFun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">h_def</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x₁</span><span class="w"> </span><span class="n">x₂</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="o">(</span><span class="n">hxeq</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="n">x₁</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="n">x₂</span><span class="o">)</span> <span class="w"> </span><span class="k">show</span><span class="w"> </span><span class="n">x₁</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x₂</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="n">only</span><span class="w"> </span><span class="o">[</span><span class="n">h_def</span><span class="o">,</span><span class="w"> </span><span class="n">sbFun</span><span class="o">,</span><span class="w"> </span><span class="bp">←</span><span class="w"> </span><span class="n">A_def</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">hxeq</span> <span class="w"> </span><span class="n">by_cases</span><span class="w"> </span><span class="n">xA</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x₁</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">x₂</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">A</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">wlog</span><span class="w"> </span><span class="n">x₁A</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x₁</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="n">generalizing</span><span class="w"> </span><span class="n">x₁</span><span class="w"> </span><span class="n">x₂</span><span class="w"> </span><span class="n">hxeq</span><span class="w"> </span><span class="n">xA</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">symm</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="n">hxeq.symm</span><span class="w"> </span><span class="n">xA.symm</span><span class="w"> </span><span class="o">(</span><span class="n">xA.resolve_left</span><span class="w"> </span><span class="n">x₁A</span><span class="o">)</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">x₂A</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x₂</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">_root_.not_imp_self.mp</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="o">(</span><span class="n">x₂nA</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x₂</span><span class="w"> </span><span class="bp">∉</span><span class="w"> </span><span class="n">A</span><span class="o">)</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">if_pos</span><span class="w"> </span><span class="n">x₁A</span><span class="o">,</span><span class="w"> </span><span class="n">if_neg</span><span class="w"> </span><span class="n">x₂nA</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">hxeq</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">A_def</span><span class="o">,</span><span class="w"> </span><span class="n">sbSet</span><span class="o">,</span><span class="w"> </span><span class="n">mem_iUnion</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">x₁A</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">x₂eq</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x₂</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">x₁</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">x₁A</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">hn</span><span class="o">⟩</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">A_def</span><span class="o">,</span><span class="w"> </span><span class="n">sbSet</span><span class="o">,</span><span class="w"> </span><span class="n">mem_iUnion</span><span class="o">]</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">sbAux</span><span class="o">]</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">x₁</span><span class="o">,</span><span class="w"> </span><span class="n">hn</span><span class="o">,</span><span class="w"> </span><span class="n">x₂eq.symm</span><span class="o">⟩</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">push_neg</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">xA</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>The proof introduces some new tactics.
-
@@ -1096,32 +1100,32 @@ The tactic <code class="docutils literal notranslate"><span class="pre">rcases</span> <span class="pre">n</span> <span class="pre">with</span> <span class="pre">_</span> <span class="pre">|</span> <span class="pre">n</span></code> splits on the cases <code class="docutils literal notranslate"><span class="pre">g</span> <span class="pre">y</span> <span class="pre">∈</span> <span class="pre">sbAux</span> <span class="pre">f</span> <span class="pre">g</span> <span class="pre">0</span></code>and <code class="docutils literal notranslate"><span class="pre">g</span> <span class="pre">y</span> <span class="pre">∈</span> <span class="pre">sbAux</span> <span class="pre">f</span> <span class="pre">g</span> <span class="pre">(n</span> <span class="pre">+</span> <span class="pre">1)</span></code>. In both cases, calling the simplifier with <code class="docutils literal notranslate"><span class="pre">simp</span> <span class="pre">[sbAux]</span></code> applies the corresponding defining equation of <code class="docutils literal notranslate"><span class="pre">sbAux</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">sb_surjective</span> <span class="o">(</span><span class="n">hg</span> <span class="o">:</span> <span class="n">Injective</span> <span class="n">g</span><span class="o">)</span> <span class="o">:</span> <span class="n">Surjective</span> <span class="o">(</span><span class="n">sbFun</span> <span class="n">f</span> <span class="n">g</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">set</span> <span class="n">A</span> <span class="o">:=</span> <span class="n">sbSet</span> <span class="n">f</span> <span class="n">g</span> <span class="k">with</span> <span class="n">A_def</span> <span class="n">set</span> <span class="n">h</span> <span class="o">:=</span> <span class="n">sbFun</span> <span class="n">f</span> <span class="n">g</span> <span class="k">with</span> <span class="n">h_def</span> <span class="n">intro</span> <span class="n">y</span> <span class="n">by_cases</span> <span class="n">gyA</span> <span class="o">:</span> <span class="n">g</span> <span class="n">y</span> <span class="bp">∈</span> <span class="n">A</span> <span class="bp">·</span> <span class="n">rw</span> <span class="o">[</span><span class="n">A_def</span><span class="o">,</span> <span class="n">sbSet</span><span class="o">,</span> <span class="n">mem_iUnion</span><span class="o">]</span> <span class="n">at</span> <span class="n">gyA</span> <span class="n">rcases</span> <span class="n">gyA</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">n</span><span class="o">,</span> <span class="n">hn</span><span class="o">⟩</span> <span class="n">rcases</span> <span class="n">n</span> <span class="k">with</span> <span class="n">_</span> <span class="bp">|</span> <span class="n">n</span> <span class="bp">·</span> <span class="n">simp</span> <span class="o">[</span><span class="n">sbAux</span><span class="o">]</span> <span class="n">at</span> <span class="n">hn</span> <span class="n">simp</span> <span class="o">[</span><span class="n">sbAux</span><span class="o">]</span> <span class="n">at</span> <span class="n">hn</span> <span class="n">rcases</span> <span class="n">hn</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">x</span><span class="o">,</span> <span class="n">xmem</span><span class="o">,</span> <span class="n">hx</span><span class="o">⟩</span> <span class="n">use</span> <span class="n">x</span> <span class="k">have</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">A</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">A_def</span><span class="o">,</span> <span class="n">sbSet</span><span class="o">,</span> <span class="n">mem_iUnion</span><span class="o">]</span> <span class="n">exact</span> <span class="o">⟨</span><span class="n">n</span><span class="o">,</span> <span class="n">xmem</span><span class="o">⟩</span> <span class="n">simp</span> <span class="n">only</span> <span class="o">[</span><span class="n">h_def</span><span class="o">,</span> <span class="n">sbFun</span><span class="o">,</span> <span class="n">if_pos</span> <span class="n">this</span><span class="o">]</span> <span class="n">exact</span> <span class="n">hg</span> <span class="n">hx</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">sb_surjective</span><span class="w"> </span><span class="o">(</span><span class="n">hg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Surjective</span><span class="w"> </span><span class="o">(</span><span class="n">sbFun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">set</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">sbSet</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">A_def</span> <span class="w"> </span><span class="n">set</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">sbFun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">h_def</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">y</span> <span class="w"> </span><span class="n">by_cases</span><span class="w"> </span><span class="n">gyA</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">A</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">A_def</span><span class="o">,</span><span class="w"> </span><span class="n">sbSet</span><span class="o">,</span><span class="w"> </span><span class="n">mem_iUnion</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">gyA</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">gyA</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">hn</span><span class="o">⟩</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">n</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">sbAux</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">hn</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">sbAux</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">hn</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">hn</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">xmem</span><span class="o">,</span><span class="w"> </span><span class="n">hx</span><span class="o">⟩</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">A_def</span><span class="o">,</span><span class="w"> </span><span class="n">sbSet</span><span class="o">,</span><span class="w"> </span><span class="n">mem_iUnion</span><span class="o">]</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">xmem</span><span class="o">⟩</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="n">only</span><span class="w"> </span><span class="o">[</span><span class="n">h_def</span><span class="o">,</span><span class="w"> </span><span class="n">sbFun</span><span class="o">,</span><span class="w"> </span><span class="n">if_pos</span><span class="w"> </span><span class="n">this</span><span class="o">]</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">hg</span><span class="w"> </span><span class="n">hx</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>We can now put it all together. The final statement is short and sweet, and the proof uses the fact that <code class="docutils literal notranslate"><span class="pre">Bijective</span> <span class="pre">h</span></code> unfolds to <code class="docutils literal notranslate"><span class="pre">Injective</span> <span class="pre">h</span> <span class="pre">∧</span> <span class="pre">Surjective</span> <span class="pre">h</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">schroeder_bernstein</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">β</span><span class="o">}</span> <span class="o">{</span><span class="n">g</span> <span class="o">:</span> <span class="n">β</span> <span class="bp">→</span> <span class="n">α</span><span class="o">}</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">Injective</span> <span class="n">f</span><span class="o">)</span> <span class="o">(</span><span class="n">hg</span> <span class="o">:</span> <span class="n">Injective</span> <span class="n">g</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">h</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">β</span><span class="o">,</span> <span class="n">Bijective</span> <span class="n">h</span> <span class="o">:=</span> <span class="o">⟨</span><span class="n">sbFun</span> <span class="n">f</span> <span class="n">g</span><span class="o">,</span> <span class="n">sb_injective</span> <span class="n">f</span> <span class="n">g</span> <span class="n">hf</span><span class="o">,</span> <span class="n">sb_surjective</span> <span class="n">f</span> <span class="n">g</span> <span class="n">hg</span><span class="o">⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">schroeder_bernstein</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">β</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">β</span><span class="o">,</span><span class="w"> </span><span class="n">Bijective</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">⟨</span><span class="n">sbFun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="o">,</span><span class="w"> </span><span class="n">sb_injective</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">hf</span><span class="o">,</span><span class="w"> </span><span class="n">sb_surjective</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">hg</span><span class="o">⟩</span> </pre></div> </div> </section>
-
-
-
@@ -1,3 +1,5 @@<!DOCTYPE html> <html class="writer-html5" lang="en" data-content_root="./"> <head>
-
@@ -6,18 +8,17 @@<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>5. Elementary Number Theory — Mathematics in Lean 0.1 documentation</title> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=80d5e7a1" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=86f27845" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" /> <link rel="stylesheet" type="text/css" href="_static/css/custom.css?v=0731ccc3" /> <link rel="shortcut icon" href="_static/favicon.ico"/> <script src="_static/jquery.js?v=8dae8fb0"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=888ff710"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> <script src="_static/jquery.js?v=5d32c60e"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=9bcbadda"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> <script src="_static/js/theme.js"></script> <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" />
-
@@ -123,18 +124,18 @@ when necessary,but we can also do it manually by rewriting or simplifying with the identifier <code class="docutils literal notranslate"><span class="pre">Nat.Coprime</span></code>. The <code class="docutils literal notranslate"><span class="pre">norm_num</span></code> tactic is smart enough to compute concrete values.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#print</span> <span class="n">Nat.Coprime</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#print</span><span class="w"> </span><span class="n">Nat.Coprime</span> <span class="kd">example</span> <span class="o">(</span><span class="n">m</span> <span class="n">n</span> <span class="o">:</span> <span class="n">Nat</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">m.Coprime</span> <span class="n">n</span><span class="o">)</span> <span class="o">:</span> <span class="n">m.gcd</span> <span class="n">n</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="n">h</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m.Coprime</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m.gcd</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">h</span> <span class="kd">example</span> <span class="o">(</span><span class="n">m</span> <span class="n">n</span> <span class="o">:</span> <span class="n">Nat</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">m.Coprime</span> <span class="n">n</span><span class="o">)</span> <span class="o">:</span> <span class="n">m.gcd</span> <span class="n">n</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">Nat.Coprime</span><span class="o">]</span> <span class="n">at</span> <span class="n">h</span> <span class="n">exact</span> <span class="n">h</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m.Coprime</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m.gcd</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">Nat.Coprime</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">Nat.Coprime</span> <span class="mi">12</span> <span class="mi">7</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">norm_num</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat.Coprime</span><span class="w"> </span><span class="mi">12</span><span class="w"> </span><span class="mi">7</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">Nat.gcd</span> <span class="mi">12</span> <span class="mi">8</span> <span class="bp">=</span> <span class="mi">4</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">norm_num</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat.gcd</span><span class="w"> </span><span class="mi">12</span><span class="w"> </span><span class="mi">8</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span> </pre></div> </div> <p>We have already encountered the <code class="docutils literal notranslate"><span class="pre">gcd</span></code> function in
-
@@ -152,24 +153,24 @@ to the natural numbers.</p><p>We also need the notion of a prime number, <code class="docutils literal notranslate"><span class="pre">Nat.Prime</span></code>. The theorem <code class="docutils literal notranslate"><span class="pre">Nat.prime_def_lt</span></code> provides one familiar characterization, and <code class="docutils literal notranslate"><span class="pre">Nat.Prime.eq_one_or_self_of_dvd</span></code> provides another.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="n">Nat.prime_def_lt</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="n">Nat.prime_def_lt</span> <span class="kd">example</span> <span class="o">(</span><span class="n">p</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">prime_p</span> <span class="o">:</span> <span class="n">Nat.Prime</span> <span class="n">p</span><span class="o">)</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">≤</span> <span class="n">p</span> <span class="bp">∧</span> <span class="bp">∀</span> <span class="n">m</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">,</span> <span class="n">m</span> <span class="bp"><</span> <span class="n">p</span> <span class="bp">→</span> <span class="n">m</span> <span class="bp">∣</span> <span class="n">p</span> <span class="bp">→</span> <span class="n">m</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rwa</span> <span class="o">[</span><span class="n">Nat.prime_def_lt</span><span class="o">]</span> <span class="n">at</span> <span class="n">prime_p</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">prime_p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat.Prime</span><span class="w"> </span><span class="n">p</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">,</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rwa</span><span class="w"> </span><span class="o">[</span><span class="n">Nat.prime_def_lt</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">prime_p</span> <span class="k">#check</span> <span class="n">Nat.Prime.eq_one_or_self_of_dvd</span> <span class="k">#check</span><span class="w"> </span><span class="n">Nat.Prime.eq_one_or_self_of_dvd</span> <span class="kd">example</span> <span class="o">(</span><span class="n">p</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">prime_p</span> <span class="o">:</span> <span class="n">Nat.Prime</span> <span class="n">p</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">m</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">,</span> <span class="n">m</span> <span class="bp">∣</span> <span class="n">p</span> <span class="bp">→</span> <span class="n">m</span> <span class="bp">=</span> <span class="mi">1</span> <span class="bp">∨</span> <span class="n">m</span> <span class="bp">=</span> <span class="n">p</span> <span class="o">:=</span> <span class="n">prime_p.eq_one_or_self_of_dvd</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">prime_p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat.Prime</span><span class="w"> </span><span class="n">p</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">,</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">prime_p.eq_one_or_self_of_dvd</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">Nat.Prime</span> <span class="mi">17</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">norm_num</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat.Prime</span><span class="w"> </span><span class="mi">17</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span> <span class="c1">-- commonly used</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">Nat.Prime</span> <span class="mi">2</span> <span class="o">:=</span> <span class="n">Nat.prime_two</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat.Prime</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Nat.prime_two</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">Nat.Prime</span> <span class="mi">3</span> <span class="o">:=</span> <span class="n">Nat.prime_three</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat.Prime</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Nat.prime_three</span> </pre></div> </div> <p>In the natural numbers, a prime number has the property that it cannot
-
@@ -187,16 +188,16 @@ if the square of a number is even, then that number is even as well.Mathlib defines the predicate <code class="docutils literal notranslate"><span class="pre">Even</span></code> in <code class="docutils literal notranslate"><span class="pre">Algebra.Group.Even</span></code>, but for reasons that will become clear below, we will simply use <code class="docutils literal notranslate"><span class="pre">2</span> <span class="pre">∣</span> <span class="pre">m</span></code> to express that <code class="docutils literal notranslate"><span class="pre">m</span></code> is even.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="n">Nat.Prime.dvd_mul</span> <span class="k">#check</span> <span class="n">Nat.Prime.dvd_mul</span> <span class="n">Nat.prime_two</span> <span class="k">#check</span> <span class="n">Nat.prime_two.dvd_mul</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="n">Nat.Prime.dvd_mul</span> <span class="k">#check</span><span class="w"> </span><span class="n">Nat.Prime.dvd_mul</span><span class="w"> </span><span class="n">Nat.prime_two</span> <span class="k">#check</span><span class="w"> </span><span class="n">Nat.prime_two.dvd_mul</span> <span class="kd">theorem</span> <span class="n">even_of_even_sqr</span> <span class="o">{</span><span class="n">m</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">∣</span> <span class="n">m</span> <span class="bp">^</span> <span class="mi">2</span><span class="o">)</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">∣</span> <span class="n">m</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">pow_two</span><span class="o">,</span> <span class="n">Nat.prime_two.dvd_mul</span><span class="o">]</span> <span class="n">at</span> <span class="n">h</span> <span class="n">cases</span> <span class="n">h</span> <span class="bp"><;></span> <span class="n">assumption</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">even_of_even_sqr</span><span class="w"> </span><span class="o">{</span><span class="n">m</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">pow_two</span><span class="o">,</span><span class="w"> </span><span class="n">Nat.prime_two.dvd_mul</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">cases</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">assumption</span> <span class="kd">example</span> <span class="o">{</span><span class="n">m</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">∣</span> <span class="n">m</span> <span class="bp">^</span> <span class="mi">2</span><span class="o">)</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">∣</span> <span class="n">m</span> <span class="o">:=</span> <span class="n">Nat.Prime.dvd_of_dvd_pow</span> <span class="n">Nat.prime_two</span> <span class="n">h</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">m</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Nat.Prime.dvd_of_dvd_pow</span><span class="w"> </span><span class="n">Nat.prime_two</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>As we proceed, you will need to become proficient at finding the facts you
-
@@ -213,32 +214,32 @@ <a class="reference external" href="https://leanprover-community.github.io/">Lean community web pages</a>,and if all else fails, don’t hesitate to ask on <a class="reference external" href="https://leanprover.zulipchat.com/">Zulip</a>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">Nat</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">c</span><span class="o">)</span> <span class="o">(</span><span class="n">h'</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">≠</span> <span class="mi">0</span><span class="o">)</span> <span class="o">:</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">c</span> <span class="o">:=</span> <span class="c1">-- apply? suggests the following:</span> <span class="o">(</span><span class="n">mul_right_inj'</span> <span class="n">h'</span><span class="o">)</span><span class="bp">.</span><span class="n">mp</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="c1">-- apply? suggests the following:</span> <span class="w"> </span><span class="o">(</span><span class="n">mul_right_inj'</span><span class="w"> </span><span class="n">h'</span><span class="o">)</span><span class="bp">.</span><span class="n">mp</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>The heart of our proof of the irrationality of the square root of two is contained in the following theorem. See if you can fill out the proof sketch, using <code class="docutils literal notranslate"><span class="pre">even_of_even_sqr</span></code> and the theorem <code class="docutils literal notranslate"><span class="pre">Nat.dvd_gcd</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">m</span> <span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">(</span><span class="n">coprime_mn</span> <span class="o">:</span> <span class="n">m.Coprime</span> <span class="n">n</span><span class="o">)</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">≠</span> <span class="mi">2</span> <span class="bp">*</span> <span class="n">n</span> <span class="bp">^</span> <span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">sqr_eq</span> <span class="k">have</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">∣</span> <span class="n">m</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="n">obtain</span> <span class="o">⟨</span><span class="n">k</span><span class="o">,</span> <span class="n">meq</span><span class="o">⟩</span> <span class="o">:=</span> <span class="n">dvd_iff_exists_eq_mul_left.mp</span> <span class="n">this</span> <span class="k">have</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">*</span> <span class="o">(</span><span class="mi">2</span> <span class="bp">*</span> <span class="n">k</span> <span class="bp">^</span> <span class="mi">2</span><span class="o">)</span> <span class="bp">=</span> <span class="mi">2</span> <span class="bp">*</span> <span class="n">n</span> <span class="bp">^</span> <span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="bp">←</span> <span class="n">sqr_eq</span><span class="o">,</span> <span class="n">meq</span><span class="o">]</span> <span class="n">ring</span> <span class="k">have</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">*</span> <span class="n">k</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">=</span> <span class="n">n</span> <span class="bp">^</span> <span class="mi">2</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">∣</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">∣</span> <span class="n">m.gcd</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">∣</span> <span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="n">norm_num</span> <span class="n">at</span> <span class="n">this</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">coprime_mn</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m.Coprime</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">sqr_eq</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">obtain</span><span class="w"> </span><span class="o">⟨</span><span class="n">k</span><span class="o">,</span><span class="w"> </span><span class="n">meq</span><span class="o">⟩</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">dvd_iff_exists_eq_mul_left.mp</span><span class="w"> </span><span class="n">this</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="bp">←</span><span class="w"> </span><span class="n">sqr_eq</span><span class="o">,</span><span class="w"> </span><span class="n">meq</span><span class="o">]</span> <span class="w"> </span><span class="n">ring</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">m.gcd</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">norm_num</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">this</span> </pre></div> </div> <p>In fact, with very few changes, we can replace <code class="docutils literal notranslate"><span class="pre">2</span></code> by an arbitrary prime.
-
@@ -248,8 +249,8 @@ <code class="docutils literal notranslate"><span class="pre">p</span> <span class="pre">∣</span> <span class="pre">1</span></code>.You can use <code class="docutils literal notranslate"><span class="pre">Nat.Prime.two_le</span></code>, which says that any prime number is greater than or equal to two, and <code class="docutils literal notranslate"><span class="pre">Nat.le_of_dvd</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">m</span> <span class="n">n</span> <span class="n">p</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">(</span><span class="n">coprime_mn</span> <span class="o">:</span> <span class="n">m.Coprime</span> <span class="n">n</span><span class="o">)</span> <span class="o">(</span><span class="n">prime_p</span> <span class="o">:</span> <span class="n">p.Prime</span><span class="o">)</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">≠</span> <span class="n">p</span> <span class="bp">*</span> <span class="n">n</span> <span class="bp">^</span> <span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">coprime_mn</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m.Coprime</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">prime_p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">p.Prime</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Let us consider another approach.
-
@@ -271,10 +272,10 @@ are prime, that any <code class="docutils literal notranslate"><span class="pre">n</span></code> greater than zero is equal to theproduct of its factors, and that if <code class="docutils literal notranslate"><span class="pre">n</span></code> is equal to the product of another list of prime numbers, then that list is a permutation of <code class="docutils literal notranslate"><span class="pre">Nat.primeFactorsList</span> <span class="pre">n</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="n">Nat.primeFactorsList</span> <span class="k">#check</span> <span class="n">Nat.prime_of_mem_primeFactorsList</span> <span class="k">#check</span> <span class="n">Nat.prod_primeFactorsList</span> <span class="k">#check</span> <span class="n">Nat.primeFactorsList_unique</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="n">Nat.primeFactorsList</span> <span class="k">#check</span><span class="w"> </span><span class="n">Nat.prime_of_mem_primeFactorsList</span> <span class="k">#check</span><span class="w"> </span><span class="n">Nat.prod_primeFactorsList</span> <span class="k">#check</span><span class="w"> </span><span class="n">Nat.primeFactorsList_unique</span> </pre></div> </div> <p>You can browse these theorems and others nearby, even though we have not
-
@@ -285,20 +286,20 @@ that represents the same data as a function.Specifically, <code class="docutils literal notranslate"><span class="pre">Nat.factorization</span> <span class="pre">n</span> <span class="pre">p</span></code>, which we can also write <code class="docutils literal notranslate"><span class="pre">n.factorization</span> <span class="pre">p</span></code>, returns the multiplicity of <code class="docutils literal notranslate"><span class="pre">p</span></code> in the prime factorization of <code class="docutils literal notranslate"><span class="pre">n</span></code>. We will use the following three facts.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">factorization_mul'</span> <span class="o">{</span><span class="n">m</span> <span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">(</span><span class="n">mnez</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">≠</span> <span class="mi">0</span><span class="o">)</span> <span class="o">(</span><span class="n">nnez</span> <span class="o">:</span> <span class="n">n</span> <span class="bp">≠</span> <span class="mi">0</span><span class="o">)</span> <span class="o">(</span><span class="n">p</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">m</span> <span class="bp">*</span> <span class="n">n</span><span class="o">)</span><span class="bp">.</span><span class="n">factorization</span> <span class="n">p</span> <span class="bp">=</span> <span class="n">m.factorization</span> <span class="n">p</span> <span class="bp">+</span> <span class="n">n.factorization</span> <span class="n">p</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">Nat.factorization_mul</span> <span class="n">mnez</span> <span class="n">nnez</span><span class="o">]</span> <span class="n">rfl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">factorization_mul'</span><span class="w"> </span><span class="o">{</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">mnez</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">nnez</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="bp">.</span><span class="n">factorization</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">m.factorization</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">n.factorization</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">Nat.factorization_mul</span><span class="w"> </span><span class="n">mnez</span><span class="w"> </span><span class="n">nnez</span><span class="o">]</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">theorem</span> <span class="n">factorization_pow'</span> <span class="o">(</span><span class="n">n</span> <span class="n">k</span> <span class="n">p</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">n</span> <span class="bp">^</span> <span class="n">k</span><span class="o">)</span><span class="bp">.</span><span class="n">factorization</span> <span class="n">p</span> <span class="bp">=</span> <span class="n">k</span> <span class="bp">*</span> <span class="n">n.factorization</span> <span class="n">p</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">Nat.factorization_pow</span><span class="o">]</span> <span class="n">rfl</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">factorization_pow'</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="n">k</span><span class="o">)</span><span class="bp">.</span><span class="n">factorization</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n.factorization</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">Nat.factorization_pow</span><span class="o">]</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">theorem</span> <span class="n">Nat.Prime.factorization'</span> <span class="o">{</span><span class="n">p</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">(</span><span class="n">prime_p</span> <span class="o">:</span> <span class="n">p.Prime</span><span class="o">)</span> <span class="o">:</span> <span class="n">p.factorization</span> <span class="n">p</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">prime_p.factorization</span><span class="o">]</span> <span class="n">simp</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">Nat.Prime.factorization'</span><span class="w"> </span><span class="o">{</span><span class="n">p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">prime_p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">p.Prime</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">p.factorization</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">prime_p.factorization</span><span class="o">]</span> <span class="w"> </span><span class="n">simp</span> </pre></div> </div> <p>In fact, <code class="docutils literal notranslate"><span class="pre">n.factorization</span></code> is defined in Lean as a function of finite support,
-
@@ -310,17 +311,17 @@ <code class="docutils literal notranslate"><span class="pre">n^2</span> <span class="pre">≠</span> <span class="pre">0</span></code> by <code class="docutils literal notranslate"><span class="pre">n</span> <span class="pre">≠</span> <span class="pre">0</span></code>. The tactic <code class="docutils literal notranslate"><span class="pre">simpa</span></code> just calls <code class="docutils literal notranslate"><span class="pre">simp</span></code>followed by <code class="docutils literal notranslate"><span class="pre">assumption</span></code>.</p> <p>See if you can use the identities above to fill in the missing parts of the proof.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">m</span> <span class="n">n</span> <span class="n">p</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">(</span><span class="n">nnz</span> <span class="o">:</span> <span class="n">n</span> <span class="bp">≠</span> <span class="mi">0</span><span class="o">)</span> <span class="o">(</span><span class="n">prime_p</span> <span class="o">:</span> <span class="n">p.Prime</span><span class="o">)</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">≠</span> <span class="n">p</span> <span class="bp">*</span> <span class="n">n</span> <span class="bp">^</span> <span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">sqr_eq</span> <span class="k">have</span> <span class="n">nsqr_nez</span> <span class="o">:</span> <span class="n">n</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">≠</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simpa</span> <span class="k">have</span> <span class="n">eq1</span> <span class="o">:</span> <span class="n">Nat.factorization</span> <span class="o">(</span><span class="n">m</span> <span class="bp">^</span> <span class="mi">2</span><span class="o">)</span> <span class="n">p</span> <span class="bp">=</span> <span class="mi">2</span> <span class="bp">*</span> <span class="n">m.factorization</span> <span class="n">p</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="n">eq2</span> <span class="o">:</span> <span class="o">(</span><span class="n">p</span> <span class="bp">*</span> <span class="n">n</span> <span class="bp">^</span> <span class="mi">2</span><span class="o">)</span><span class="bp">.</span><span class="n">factorization</span> <span class="n">p</span> <span class="bp">=</span> <span class="mi">2</span> <span class="bp">*</span> <span class="n">n.factorization</span> <span class="n">p</span> <span class="bp">+</span> <span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">*</span> <span class="n">m.factorization</span> <span class="n">p</span> <span class="bp">%</span> <span class="mi">2</span> <span class="bp">=</span> <span class="o">(</span><span class="mi">2</span> <span class="bp">*</span> <span class="n">n.factorization</span> <span class="n">p</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">)</span> <span class="bp">%</span> <span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="bp">←</span> <span class="n">eq1</span><span class="o">,</span> <span class="n">sqr_eq</span><span class="o">,</span> <span class="n">eq2</span><span class="o">]</span> <span class="n">rw</span> <span class="o">[</span><span class="n">add_comm</span><span class="o">,</span> <span class="n">Nat.add_mul_mod_self_left</span><span class="o">,</span> <span class="n">Nat.mul_mod_right</span><span class="o">]</span> <span class="n">at</span> <span class="n">this</span> <span class="n">norm_num</span> <span class="n">at</span> <span class="n">this</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">nnz</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">prime_p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">p.Prime</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">sqr_eq</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">nsqr_nez</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simpa</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">eq1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat.factorization</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">m.factorization</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">eq2</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">p</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="bp">.</span><span class="n">factorization</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n.factorization</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">m.factorization</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n.factorization</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="bp">←</span><span class="w"> </span><span class="n">eq1</span><span class="o">,</span><span class="w"> </span><span class="n">sqr_eq</span><span class="o">,</span><span class="w"> </span><span class="n">eq2</span><span class="o">]</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">add_comm</span><span class="o">,</span><span class="w"> </span><span class="n">Nat.add_mul_mod_self_left</span><span class="o">,</span><span class="w"> </span><span class="n">Nat.mul_mod_right</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">this</span> <span class="w"> </span><span class="n">norm_num</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">this</span> </pre></div> </div> <p>A nice thing about this proof is that it also generalizes. There is
-
@@ -347,20 +348,20 @@ to finish it off.</p><p>Note that this example does not assume that <code class="docutils literal notranslate"><span class="pre">p</span></code> is prime, but the conclusion is trivial when <code class="docutils literal notranslate"><span class="pre">p</span></code> is not prime since <code class="docutils literal notranslate"><span class="pre">r.factorization</span> <span class="pre">p</span></code> is then zero by definition, and the proof works in all cases anyway.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">m</span> <span class="n">n</span> <span class="n">k</span> <span class="n">r</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">(</span><span class="n">nnz</span> <span class="o">:</span> <span class="n">n</span> <span class="bp">≠</span> <span class="mi">0</span><span class="o">)</span> <span class="o">(</span><span class="n">pow_eq</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">^</span> <span class="n">k</span> <span class="bp">=</span> <span class="n">r</span> <span class="bp">*</span> <span class="n">n</span> <span class="bp">^</span> <span class="n">k</span><span class="o">)</span> <span class="o">{</span><span class="n">p</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">:</span> <span class="n">k</span> <span class="bp">∣</span> <span class="n">r.factorization</span> <span class="n">p</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rcases</span> <span class="n">r</span> <span class="k">with</span> <span class="n">_</span> <span class="bp">|</span> <span class="n">r</span> <span class="bp">·</span> <span class="n">simp</span> <span class="k">have</span> <span class="n">npow_nz</span> <span class="o">:</span> <span class="n">n</span> <span class="bp">^</span> <span class="n">k</span> <span class="bp">≠</span> <span class="mi">0</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">npowz</span> <span class="bp">↦</span> <span class="n">nnz</span> <span class="o">(</span><span class="n">pow_eq_zero</span> <span class="n">npowz</span><span class="o">)</span> <span class="k">have</span> <span class="n">eq1</span> <span class="o">:</span> <span class="o">(</span><span class="n">m</span> <span class="bp">^</span> <span class="n">k</span><span class="o">)</span><span class="bp">.</span><span class="n">factorization</span> <span class="n">p</span> <span class="bp">=</span> <span class="n">k</span> <span class="bp">*</span> <span class="n">m.factorization</span> <span class="n">p</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="n">eq2</span> <span class="o">:</span> <span class="o">((</span><span class="n">r</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">)</span> <span class="bp">*</span> <span class="n">n</span> <span class="bp">^</span> <span class="n">k</span><span class="o">)</span><span class="bp">.</span><span class="n">factorization</span> <span class="n">p</span> <span class="bp">=</span> <span class="n">k</span> <span class="bp">*</span> <span class="n">n.factorization</span> <span class="n">p</span> <span class="bp">+</span> <span class="o">(</span><span class="n">r</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">)</span><span class="bp">.</span><span class="n">factorization</span> <span class="n">p</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="o">:</span> <span class="n">r.succ.factorization</span> <span class="n">p</span> <span class="bp">=</span> <span class="n">k</span> <span class="bp">*</span> <span class="n">m.factorization</span> <span class="n">p</span> <span class="bp">-</span> <span class="n">k</span> <span class="bp">*</span> <span class="n">n.factorization</span> <span class="n">p</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="bp">←</span> <span class="n">eq1</span><span class="o">,</span> <span class="n">pow_eq</span><span class="o">,</span> <span class="n">eq2</span><span class="o">,</span> <span class="n">add_comm</span><span class="o">,</span> <span class="n">Nat.add_sub_cancel</span><span class="o">]</span> <span class="n">rw</span> <span class="o">[</span><span class="n">this</span><span class="o">]</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">nnz</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">pow_eq</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="n">k</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">r.factorization</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">r</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">npow_nz</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">npowz</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">nnz</span><span class="w"> </span><span class="o">(</span><span class="n">pow_eq_zero</span><span class="w"> </span><span class="n">npowz</span><span class="o">)</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">eq1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="n">k</span><span class="o">)</span><span class="bp">.</span><span class="n">factorization</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">m.factorization</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">eq2</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">((</span><span class="n">r</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="n">k</span><span class="o">)</span><span class="bp">.</span><span class="n">factorization</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">=</span> <span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n.factorization</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="bp">.</span><span class="n">factorization</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">r.succ.factorization</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">m.factorization</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n.factorization</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="bp">←</span><span class="w"> </span><span class="n">eq1</span><span class="o">,</span><span class="w"> </span><span class="n">pow_eq</span><span class="o">,</span><span class="w"> </span><span class="n">eq2</span><span class="o">,</span><span class="w"> </span><span class="n">add_comm</span><span class="o">,</span><span class="w"> </span><span class="n">Nat.add_sub_cancel</span><span class="o">]</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">this</span><span class="o">]</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>There are a number of ways in which we might want to improve on these results.
-
@@ -410,9 +411,9 @@ Lean’s foundation allows us to declare <em>inductive types</em>,which are types generated inductively by a given list of <em>constructors</em>. In Lean, the natural numbers are declared as follows.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">inductive</span> <span class="n">Nat</span> <span class="n">where</span> <span class="bp">|</span> <span class="n">zero</span> <span class="o">:</span> <span class="n">Nat</span> <span class="bp">|</span> <span class="n">succ</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">Nat</span><span class="o">)</span> <span class="o">:</span> <span class="n">Nat</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">inductive</span><span class="w"> </span><span class="n">Nat</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">zero</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">succ</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat</span> </pre></div> </div> <p>You can find this in the library by writing <code class="docutils literal notranslate"><span class="pre">#check</span> <span class="pre">Nat</span></code> and
-
@@ -426,11 +427,11 @@ representations, but we don’t have to worry about the details of that now.)</p><p>What “freely” means for the working mathematician is that the type <code class="docutils literal notranslate"><span class="pre">Nat</span></code> has an element <code class="docutils literal notranslate"><span class="pre">zero</span></code> and an injective successor function <code class="docutils literal notranslate"><span class="pre">succ</span></code> whose image does not include <code class="docutils literal notranslate"><span class="pre">zero</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">Nat</span><span class="o">)</span> <span class="o">:</span> <span class="n">n.succ</span> <span class="bp">≠</span> <span class="n">Nat.zero</span> <span class="o">:=</span> <span class="n">Nat.succ_ne_zero</span> <span class="n">n</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">n.succ</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">Nat.zero</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Nat.succ_ne_zero</span><span class="w"> </span><span class="n">n</span> <span class="kd">example</span> <span class="o">(</span><span class="n">m</span> <span class="n">n</span> <span class="o">:</span> <span class="n">Nat</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">m.succ</span> <span class="bp">=</span> <span class="n">n.succ</span><span class="o">)</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">=</span> <span class="n">n</span> <span class="o">:=</span> <span class="n">Nat.succ.inj</span> <span class="n">h</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m.succ</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">n.succ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Nat.succ.inj</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>What the word “inductively” means for the working mathematician is that
-
@@ -439,9 +440,9 @@ and a principle of definition by recursion.This section will show you how to use these.</p> <p>Here is an example of a recursive definition of the factorial function.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">fac</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">ℕ</span> <span class="bp">|</span> <span class="mi">0</span> <span class="bp">=></span> <span class="mi">1</span> <span class="bp">|</span> <span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span> <span class="bp">=></span> <span class="o">(</span><span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">)</span> <span class="bp">*</span> <span class="n">fac</span> <span class="n">n</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">fac</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℕ</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="mi">1</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">fac</span><span class="w"> </span><span class="n">n</span> </pre></div> </div> <p>The syntax takes some getting used to.
-
@@ -450,23 +451,23 @@ The next two lines provide the base case and inductive stepfor a recursive definition. These equations hold definitionally, but they can also be used manually by giving the name <code class="docutils literal notranslate"><span class="pre">fac</span></code> to <code class="docutils literal notranslate"><span class="pre">simp</span></code> or <code class="docutils literal notranslate"><span class="pre">rw</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">fac</span> <span class="mi">0</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="n">rfl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">fac</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">fac</span> <span class="mi">0</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">fac</span><span class="o">]</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">fac</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">fac</span><span class="o">]</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">fac</span> <span class="mi">0</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="o">[</span><span class="n">fac</span><span class="o">]</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">fac</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">fac</span><span class="o">]</span> <span class="kd">example</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:</span> <span class="n">fac</span> <span class="o">(</span><span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">)</span> <span class="bp">=</span> <span class="o">(</span><span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">)</span> <span class="bp">*</span> <span class="n">fac</span> <span class="n">n</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">fac</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">fac</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">example</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:</span> <span class="n">fac</span> <span class="o">(</span><span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">)</span> <span class="bp">=</span> <span class="o">(</span><span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">)</span> <span class="bp">*</span> <span class="n">fac</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">fac</span><span class="o">]</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">fac</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">fac</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">fac</span><span class="o">]</span> <span class="kd">example</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:</span> <span class="n">fac</span> <span class="o">(</span><span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">)</span> <span class="bp">=</span> <span class="o">(</span><span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">)</span> <span class="bp">*</span> <span class="n">fac</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="o">[</span><span class="n">fac</span><span class="o">]</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">fac</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">fac</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">fac</span><span class="o">]</span> </pre></div> </div> <p>The factorial function is actually already defined in Mathlib as
-
@@ -489,26 +490,26 @@ and a required to prove <code class="docutils literal notranslate"><span class="pre">0</span> <span class="pre"><</span> <span class="pre">fac</span> <span class="pre">(n</span> <span class="pre">+</span> <span class="pre">1)</span></code>.The phrase <code class="docutils literal notranslate"><span class="pre">with</span> <span class="pre">n</span> <span class="pre">ih</span></code> serves to name the variable and the assumption for the inductive hypothesis, and you can choose whatever names you want for them.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">fac_pos</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">fac</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">induction'</span> <span class="n">n</span> <span class="k">with</span> <span class="n">n</span> <span class="n">ih</span> <span class="bp">·</span> <span class="n">rw</span> <span class="o">[</span><span class="n">fac</span><span class="o">]</span> <span class="n">exact</span> <span class="n">zero_lt_one</span> <span class="n">rw</span> <span class="o">[</span><span class="n">fac</span><span class="o">]</span> <span class="n">exact</span> <span class="n">mul_pos</span> <span class="n">n.succ_pos</span> <span class="n">ih</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">fac_pos</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">fac</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">induction'</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">ih</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">fac</span><span class="o">]</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">zero_lt_one</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">fac</span><span class="o">]</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">mul_pos</span><span class="w"> </span><span class="n">n.succ_pos</span><span class="w"> </span><span class="n">ih</span> </pre></div> </div> <p>The <code class="docutils literal notranslate"><span class="pre">induction</span></code> tactic is smart enough to include hypotheses that depend on the induction variable as part of the induction hypothesis. Step through the next example to see what is going on.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">dvd_fac</span> <span class="o">{</span><span class="n">i</span> <span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">(</span><span class="n">ipos</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">i</span><span class="o">)</span> <span class="o">(</span><span class="n">ile</span> <span class="o">:</span> <span class="n">i</span> <span class="bp">≤</span> <span class="n">n</span><span class="o">)</span> <span class="o">:</span> <span class="n">i</span> <span class="bp">∣</span> <span class="n">fac</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">induction'</span> <span class="n">n</span> <span class="k">with</span> <span class="n">n</span> <span class="n">ih</span> <span class="bp">·</span> <span class="n">exact</span> <span class="n">absurd</span> <span class="n">ipos</span> <span class="o">(</span><span class="n">not_lt_of_ge</span> <span class="n">ile</span><span class="o">)</span> <span class="n">rw</span> <span class="o">[</span><span class="n">fac</span><span class="o">]</span> <span class="n">rcases</span> <span class="n">Nat.of_le_succ</span> <span class="n">ile</span> <span class="k">with</span> <span class="n">h</span> <span class="bp">|</span> <span class="n">h</span> <span class="bp">·</span> <span class="n">apply</span> <span class="n">dvd_mul_of_dvd_right</span> <span class="o">(</span><span class="n">ih</span> <span class="n">h</span><span class="o">)</span> <span class="n">rw</span> <span class="o">[</span><span class="n">h</span><span class="o">]</span> <span class="n">apply</span> <span class="n">dvd_mul_right</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">dvd_fac</span><span class="w"> </span><span class="o">{</span><span class="n">i</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">ipos</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ile</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">fac</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">induction'</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">ih</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">absurd</span><span class="w"> </span><span class="n">ipos</span><span class="w"> </span><span class="o">(</span><span class="n">not_lt_of_ge</span><span class="w"> </span><span class="n">ile</span><span class="o">)</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">fac</span><span class="o">]</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">Nat.of_le_succ</span><span class="w"> </span><span class="n">ile</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">dvd_mul_of_dvd_right</span><span class="w"> </span><span class="o">(</span><span class="n">ih</span><span class="w"> </span><span class="n">h</span><span class="o">)</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">h</span><span class="o">]</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">dvd_mul_right</span> </pre></div> </div> <p>The following example provides a crude lower bound for the factorial
-
@@ -518,10 +519,10 @@ so that the remainder of the proof starts with the case<span class="math notranslate nohighlight">\(n = 1\)</span>. See if you can complete the argument with a proof by induction using <code class="docutils literal notranslate"><span class="pre">pow_succ</span></code> or <code class="docutils literal notranslate"><span class="pre">pow_succ'</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">pow_two_le_fac</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">^</span> <span class="o">(</span><span class="n">n</span> <span class="bp">-</span> <span class="mi">1</span><span class="o">)</span> <span class="bp">≤</span> <span class="n">fac</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rcases</span> <span class="n">n</span> <span class="k">with</span> <span class="n">_</span> <span class="bp">|</span> <span class="n">n</span> <span class="bp">·</span> <span class="n">simp</span> <span class="o">[</span><span class="n">fac</span><span class="o">]</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">pow_two_le_fac</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">fac</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">n</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">fac</span><span class="o">]</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Induction is often used to prove identities involving finite sums and
-
@@ -540,50 +541,50 @@ it supports in the next section, and again in a later chapter.For now, we will only make use of <code class="docutils literal notranslate"><span class="pre">Finset.range</span> <span class="pre">n</span></code>, which is the finite set of natural numbers less than <code class="docutils literal notranslate"><span class="pre">n</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">(</span><span class="n">s</span> <span class="o">:</span> <span class="n">Finset</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Finset</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span> <span class="k">#check</span> <span class="n">Finset.sum</span> <span class="n">s</span> <span class="n">f</span> <span class="k">#check</span> <span class="n">Finset.prod</span> <span class="n">s</span> <span class="n">f</span> <span class="k">#check</span><span class="w"> </span><span class="n">Finset.sum</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">f</span> <span class="k">#check</span><span class="w"> </span><span class="n">Finset.prod</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">f</span> <span class="kn">open</span> <span class="n">BigOperators</span> <span class="kn">open</span> <span class="n">Finset</span> <span class="kn">open</span><span class="w"> </span><span class="n">BigOperators</span> <span class="kn">open</span><span class="w"> </span><span class="n">Finset</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">s.sum</span> <span class="n">f</span> <span class="bp">=</span> <span class="bp">∑</span> <span class="n">x</span> <span class="k">in</span> <span class="n">s</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s.sum</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">∑</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">s.prod</span> <span class="n">f</span> <span class="bp">=</span> <span class="bp">∏</span> <span class="n">x</span> <span class="k">in</span> <span class="n">s</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s.prod</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">∏</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">range</span> <span class="n">n</span><span class="o">)</span><span class="bp">.</span><span class="n">sum</span> <span class="n">f</span> <span class="bp">=</span> <span class="bp">∑</span> <span class="n">x</span> <span class="k">in</span> <span class="n">range</span> <span class="n">n</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">range</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="bp">.</span><span class="n">sum</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">∑</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">range</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">range</span> <span class="n">n</span><span class="o">)</span><span class="bp">.</span><span class="n">prod</span> <span class="n">f</span> <span class="bp">=</span> <span class="bp">∏</span> <span class="n">x</span> <span class="k">in</span> <span class="n">range</span> <span class="n">n</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">range</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="bp">.</span><span class="n">prod</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">∏</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">range</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> </pre></div> </div> <p>The facts <code class="docutils literal notranslate"><span class="pre">Finset.sum_range_zero</span></code> and <code class="docutils literal notranslate"><span class="pre">Finset.sum_range_succ</span></code> provide a recursive description of summation up to <span class="math notranslate nohighlight">\(n\)</span>, and similarly for products.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∑</span> <span class="n">x</span> <span class="k">in</span> <span class="n">range</span> <span class="mi">0</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="n">Finset.sum_range_zero</span> <span class="n">f</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∑</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">range</span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Finset.sum_range_zero</span><span class="w"> </span><span class="n">f</span> <span class="kd">example</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∑</span> <span class="n">x</span> <span class="k">in</span> <span class="n">range</span> <span class="n">n.succ</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">=</span> <span class="bp">∑</span> <span class="n">x</span> <span class="k">in</span> <span class="n">range</span> <span class="n">n</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">f</span> <span class="n">n</span> <span class="o">:=</span> <span class="n">Finset.sum_range_succ</span> <span class="n">f</span> <span class="n">n</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∑</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">range</span><span class="w"> </span><span class="n">n.succ</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">∑</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">range</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Finset.sum_range_succ</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">n</span> <span class="kd">example</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∏</span> <span class="n">x</span> <span class="k">in</span> <span class="n">range</span> <span class="mi">0</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="n">Finset.prod_range_zero</span> <span class="n">f</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∏</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">range</span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Finset.prod_range_zero</span><span class="w"> </span><span class="n">f</span> <span class="kd">example</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∏</span> <span class="n">x</span> <span class="k">in</span> <span class="n">range</span> <span class="n">n.succ</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">=</span> <span class="o">(</span><span class="bp">∏</span> <span class="n">x</span> <span class="k">in</span> <span class="n">range</span> <span class="n">n</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span><span class="o">)</span> <span class="bp">*</span> <span class="n">f</span> <span class="n">n</span> <span class="o">:=</span> <span class="n">Finset.prod_range_succ</span> <span class="n">f</span> <span class="n">n</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∏</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">range</span><span class="w"> </span><span class="n">n.succ</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="bp">∏</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">range</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Finset.prod_range_succ</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">n</span> </pre></div> </div> <p>The first identity in each pair holds definitionally, which is to say, you can replace the proofs by <code class="docutils literal notranslate"><span class="pre">rfl</span></code>.</p> <p>The following expresses the factorial function that we defined as a product.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:</span> <span class="n">fac</span> <span class="n">n</span> <span class="bp">=</span> <span class="bp">∏</span> <span class="n">i</span> <span class="k">in</span> <span class="n">range</span> <span class="n">n</span><span class="o">,</span> <span class="o">(</span><span class="n">i</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">induction'</span> <span class="n">n</span> <span class="k">with</span> <span class="n">n</span> <span class="n">ih</span> <span class="bp">·</span> <span class="n">simp</span> <span class="o">[</span><span class="n">fac</span><span class="o">,</span> <span class="n">prod_range_zero</span><span class="o">]</span> <span class="n">simp</span> <span class="o">[</span><span class="n">fac</span><span class="o">,</span> <span class="n">ih</span><span class="o">,</span> <span class="n">prod_range_succ</span><span class="o">,</span> <span class="n">mul_comm</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">fac</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">∏</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">range</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="o">(</span><span class="n">i</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">induction'</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">ih</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">fac</span><span class="o">,</span><span class="w"> </span><span class="n">prod_range_zero</span><span class="o">]</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">fac</span><span class="o">,</span><span class="w"> </span><span class="n">ih</span><span class="o">,</span><span class="w"> </span><span class="n">prod_range_succ</span><span class="o">,</span><span class="w"> </span><span class="n">mul_comm</span><span class="o">]</span> </pre></div> </div> <p>The fact that we include <code class="docutils literal notranslate"><span class="pre">mul_comm</span></code> as a simplification rule deserves
-
@@ -597,8 +598,8 @@ The following example shows that simplifying using the three rules<code class="docutils literal notranslate"><span class="pre">mul_assoc</span></code>, <code class="docutils literal notranslate"><span class="pre">mul_comm</span></code>, and <code class="docutils literal notranslate"><span class="pre">mul_left_comm</span></code> manages to identify products that are the same up to the placement of parentheses and ordering of variables.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="n">d</span> <span class="n">e</span> <span class="n">f</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="o">(</span><span class="n">b</span> <span class="bp">*</span> <span class="n">c</span> <span class="bp">*</span> <span class="n">f</span> <span class="bp">*</span> <span class="o">(</span><span class="n">d</span> <span class="bp">*</span> <span class="n">e</span><span class="o">))</span> <span class="bp">=</span> <span class="n">d</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">f</span> <span class="bp">*</span> <span class="n">e</span><span class="o">)</span> <span class="bp">*</span> <span class="o">(</span><span class="n">c</span> <span class="bp">*</span> <span class="n">b</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="o">[</span><span class="n">mul_assoc</span><span class="o">,</span> <span class="n">mul_comm</span><span class="o">,</span> <span class="n">mul_left_comm</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">d</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">e</span><span class="o">))</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">e</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">mul_assoc</span><span class="o">,</span><span class="w"> </span><span class="n">mul_comm</span><span class="o">,</span><span class="w"> </span><span class="n">mul_left_comm</span><span class="o">]</span> </pre></div> </div> <p>Roughly, the rules work by pushing parentheses to the right
-
@@ -612,18 +613,18 @@ The first step of the proof clears the denominator.This is generally useful when formalizing identities, because calculations with division generally have side conditions. (It is similarly useful to avoid using subtraction on the natural numbers when possible.)</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">sum_id</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∑</span> <span class="n">i</span> <span class="k">in</span> <span class="n">range</span> <span class="o">(</span><span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">),</span> <span class="n">i</span> <span class="bp">=</span> <span class="n">n</span> <span class="bp">*</span> <span class="o">(</span><span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">)</span> <span class="bp">/</span> <span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">symm</span><span class="bp">;</span> <span class="n">apply</span> <span class="n">Nat.div_eq_of_eq_mul_right</span> <span class="o">(</span><span class="kd">by</span> <span class="n">norm_num</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="mi">2</span><span class="o">)</span> <span class="n">induction'</span> <span class="n">n</span> <span class="k">with</span> <span class="n">n</span> <span class="n">ih</span> <span class="bp">·</span> <span class="n">simp</span> <span class="n">rw</span> <span class="o">[</span><span class="n">Finset.sum_range_succ</span><span class="o">,</span> <span class="n">mul_add</span> <span class="mi">2</span><span class="o">,</span> <span class="bp">←</span> <span class="n">ih</span><span class="o">]</span> <span class="n">ring</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">sum_id</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∑</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">range</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">),</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">symm</span><span class="bp">;</span><span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">Nat.div_eq_of_eq_mul_right</span><span class="w"> </span><span class="o">(</span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span> <span class="w"> </span><span class="n">induction'</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">ih</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">Finset.sum_range_succ</span><span class="o">,</span><span class="w"> </span><span class="n">mul_add</span><span class="w"> </span><span class="mi">2</span><span class="o">,</span><span class="w"> </span><span class="bp">←</span><span class="w"> </span><span class="n">ih</span><span class="o">]</span> <span class="w"> </span><span class="n">ring</span> </pre></div> </div> <p>We encourage you to prove the analogous identity for sums of squares, and other identities you can find on the web.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">sum_sqr</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∑</span> <span class="n">i</span> <span class="k">in</span> <span class="n">range</span> <span class="o">(</span><span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">),</span> <span class="n">i</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">=</span> <span class="n">n</span> <span class="bp">*</span> <span class="o">(</span><span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">)</span> <span class="bp">*</span> <span class="o">(</span><span class="mi">2</span> <span class="bp">*</span> <span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">)</span> <span class="bp">/</span> <span class="mi">6</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">sum_sqr</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∑</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">range</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">),</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">6</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>In Lean’s core library, addition and multiplication are themselves defined
-
@@ -662,48 +663,48 @@ Remember that truncated subtraction cuts off at zero.To define that, it is useful to define a predecessor function, <code class="docutils literal notranslate"><span class="pre">pred</span></code>, that subtracts one from any nonzero number and fixes zero. The function <code class="docutils literal notranslate"><span class="pre">pred</span></code> can be defined by a simple instance of recursion.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">inductive</span> <span class="n">MyNat</span> <span class="n">where</span> <span class="bp">|</span> <span class="n">zero</span> <span class="o">:</span> <span class="n">MyNat</span> <span class="bp">|</span> <span class="n">succ</span> <span class="o">:</span> <span class="n">MyNat</span> <span class="bp">→</span> <span class="n">MyNat</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">inductive</span><span class="w"> </span><span class="n">MyNat</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">zero</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MyNat</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">succ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MyNat</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">MyNat</span> <span class="kn">namespace</span> <span class="n">MyNat</span> <span class="kn">namespace</span><span class="w"> </span><span class="n">MyNat</span> <span class="kd">def</span> <span class="n">add</span> <span class="o">:</span> <span class="n">MyNat</span> <span class="bp">→</span> <span class="n">MyNat</span> <span class="bp">→</span> <span class="n">MyNat</span> <span class="bp">|</span> <span class="n">x</span><span class="o">,</span> <span class="n">zero</span> <span class="bp">=></span> <span class="n">x</span> <span class="bp">|</span> <span class="n">x</span><span class="o">,</span> <span class="n">succ</span> <span class="n">y</span> <span class="bp">=></span> <span class="n">succ</span> <span class="o">(</span><span class="n">add</span> <span class="n">x</span> <span class="n">y</span><span class="o">)</span> <span class="kd">def</span><span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MyNat</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">MyNat</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">MyNat</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">zero</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">succ</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="n">succ</span><span class="w"> </span><span class="o">(</span><span class="n">add</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="o">)</span> <span class="kd">def</span> <span class="n">mul</span> <span class="o">:</span> <span class="n">MyNat</span> <span class="bp">→</span> <span class="n">MyNat</span> <span class="bp">→</span> <span class="n">MyNat</span> <span class="bp">|</span> <span class="n">x</span><span class="o">,</span> <span class="n">zero</span> <span class="bp">=></span> <span class="n">zero</span> <span class="bp">|</span> <span class="n">x</span><span class="o">,</span> <span class="n">succ</span> <span class="n">y</span> <span class="bp">=></span> <span class="n">add</span> <span class="o">(</span><span class="n">mul</span> <span class="n">x</span> <span class="n">y</span><span class="o">)</span> <span class="n">x</span> <span class="kd">def</span><span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MyNat</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">MyNat</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">MyNat</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">zero</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="n">zero</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">succ</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="o">(</span><span class="n">mul</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="n">x</span> <span class="kd">theorem</span> <span class="n">zero_add</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">MyNat</span><span class="o">)</span> <span class="o">:</span> <span class="n">add</span> <span class="n">zero</span> <span class="n">n</span> <span class="bp">=</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">induction'</span> <span class="n">n</span> <span class="k">with</span> <span class="n">n</span> <span class="n">ih</span> <span class="bp">·</span> <span class="n">rfl</span> <span class="n">rw</span> <span class="o">[</span><span class="n">add</span><span class="o">,</span> <span class="n">ih</span><span class="o">]</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">zero_add</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MyNat</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="n">zero</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">induction'</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">ih</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rfl</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">add</span><span class="o">,</span><span class="w"> </span><span class="n">ih</span><span class="o">]</span> <span class="kd">theorem</span> <span class="n">succ_add</span> <span class="o">(</span><span class="n">m</span> <span class="n">n</span> <span class="o">:</span> <span class="n">MyNat</span><span class="o">)</span> <span class="o">:</span> <span class="n">add</span> <span class="o">(</span><span class="n">succ</span> <span class="n">m</span><span class="o">)</span> <span class="n">n</span> <span class="bp">=</span> <span class="n">succ</span> <span class="o">(</span><span class="n">add</span> <span class="n">m</span> <span class="n">n</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">induction'</span> <span class="n">n</span> <span class="k">with</span> <span class="n">n</span> <span class="n">ih</span> <span class="bp">·</span> <span class="n">rfl</span> <span class="n">rw</span> <span class="o">[</span><span class="n">add</span><span class="o">,</span> <span class="n">ih</span><span class="o">]</span> <span class="n">rfl</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">succ_add</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MyNat</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="o">(</span><span class="n">succ</span><span class="w"> </span><span class="n">m</span><span class="o">)</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">succ</span><span class="w"> </span><span class="o">(</span><span class="n">add</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">induction'</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">ih</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rfl</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">add</span><span class="o">,</span><span class="w"> </span><span class="n">ih</span><span class="o">]</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">theorem</span> <span class="n">add_comm</span> <span class="o">(</span><span class="n">m</span> <span class="n">n</span> <span class="o">:</span> <span class="n">MyNat</span><span class="o">)</span> <span class="o">:</span> <span class="n">add</span> <span class="n">m</span> <span class="n">n</span> <span class="bp">=</span> <span class="n">add</span> <span class="n">n</span> <span class="n">m</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">induction'</span> <span class="n">n</span> <span class="k">with</span> <span class="n">n</span> <span class="n">ih</span> <span class="bp">·</span> <span class="n">rw</span> <span class="o">[</span><span class="n">zero_add</span><span class="o">]</span> <span class="n">rfl</span> <span class="n">rw</span> <span class="o">[</span><span class="n">add</span><span class="o">,</span> <span class="n">succ_add</span><span class="o">,</span> <span class="n">ih</span><span class="o">]</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">add_comm</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MyNat</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">induction'</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">ih</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">zero_add</span><span class="o">]</span> <span class="w"> </span><span class="n">rfl</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">add</span><span class="o">,</span><span class="w"> </span><span class="n">succ_add</span><span class="o">,</span><span class="w"> </span><span class="n">ih</span><span class="o">]</span> <span class="kd">theorem</span> <span class="n">add_assoc</span> <span class="o">(</span><span class="n">m</span> <span class="n">n</span> <span class="n">k</span> <span class="o">:</span> <span class="n">MyNat</span><span class="o">)</span> <span class="o">:</span> <span class="n">add</span> <span class="o">(</span><span class="n">add</span> <span class="n">m</span> <span class="n">n</span><span class="o">)</span> <span class="n">k</span> <span class="bp">=</span> <span class="n">add</span> <span class="n">m</span> <span class="o">(</span><span class="n">add</span> <span class="n">n</span> <span class="n">k</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">theorem</span> <span class="n">mul_add</span> <span class="o">(</span><span class="n">m</span> <span class="n">n</span> <span class="n">k</span> <span class="o">:</span> <span class="n">MyNat</span><span class="o">)</span> <span class="o">:</span> <span class="n">mul</span> <span class="n">m</span> <span class="o">(</span><span class="n">add</span> <span class="n">n</span> <span class="n">k</span><span class="o">)</span> <span class="bp">=</span> <span class="n">add</span> <span class="o">(</span><span class="n">mul</span> <span class="n">m</span> <span class="n">n</span><span class="o">)</span> <span class="o">(</span><span class="n">mul</span> <span class="n">m</span> <span class="n">k</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">theorem</span> <span class="n">zero_mul</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">MyNat</span><span class="o">)</span> <span class="o">:</span> <span class="n">mul</span> <span class="n">zero</span> <span class="n">n</span> <span class="bp">=</span> <span class="n">zero</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">theorem</span> <span class="n">succ_mul</span> <span class="o">(</span><span class="n">m</span> <span class="n">n</span> <span class="o">:</span> <span class="n">MyNat</span><span class="o">)</span> <span class="o">:</span> <span class="n">mul</span> <span class="o">(</span><span class="n">succ</span> <span class="n">m</span><span class="o">)</span> <span class="n">n</span> <span class="bp">=</span> <span class="n">add</span> <span class="o">(</span><span class="n">mul</span> <span class="n">m</span> <span class="n">n</span><span class="o">)</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">theorem</span> <span class="n">mul_comm</span> <span class="o">(</span><span class="n">m</span> <span class="n">n</span> <span class="o">:</span> <span class="n">MyNat</span><span class="o">)</span> <span class="o">:</span> <span class="n">mul</span> <span class="n">m</span> <span class="n">n</span> <span class="bp">=</span> <span class="n">mul</span> <span class="n">n</span> <span class="n">m</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">end</span> <span class="n">MyNat</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">add_assoc</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MyNat</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="o">(</span><span class="n">add</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">(</span><span class="n">add</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">k</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">mul_add</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MyNat</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">(</span><span class="n">add</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">k</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="o">(</span><span class="n">mul</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">mul</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">k</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">zero_mul</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MyNat</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="n">zero</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">zero</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">succ_mul</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MyNat</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="o">(</span><span class="n">succ</span><span class="w"> </span><span class="n">m</span><span class="o">)</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="o">(</span><span class="n">mul</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">mul_comm</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MyNat</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">end</span><span class="w"> </span><span class="n">MyNat</span> </pre></div> </div> </section>
-
@@ -728,12 +729,12 @@ annoying to formalize.Here we consider a few ways to do it.</p> <p>To start with, we can use the <code class="docutils literal notranslate"><span class="pre">cases</span></code> tactic and the fact that the successor function respects the ordering on the natural numbers.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">two_le</span> <span class="o">{</span><span class="n">m</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">(</span><span class="n">h0</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">≠</span> <span class="mi">0</span><span class="o">)</span> <span class="o">(</span><span class="n">h1</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">≠</span> <span class="mi">1</span><span class="o">)</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">≤</span> <span class="n">m</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">cases</span> <span class="n">m</span><span class="bp">;</span> <span class="n">contradiction</span> <span class="n">case</span> <span class="n">succ</span> <span class="n">m</span> <span class="bp">=></span> <span class="n">cases</span> <span class="n">m</span><span class="bp">;</span> <span class="n">contradiction</span> <span class="n">repeat</span> <span class="n">apply</span> <span class="n">Nat.succ_le_succ</span> <span class="n">apply</span> <span class="n">zero_le</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">two_le</span><span class="w"> </span><span class="o">{</span><span class="n">m</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h0</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">cases</span><span class="w"> </span><span class="n">m</span><span class="bp">;</span><span class="w"> </span><span class="n">contradiction</span> <span class="w"> </span><span class="n">case</span><span class="w"> </span><span class="n">succ</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">=></span> <span class="w"> </span><span class="n">cases</span><span class="w"> </span><span class="n">m</span><span class="bp">;</span><span class="w"> </span><span class="n">contradiction</span> <span class="w"> </span><span class="n">repeat</span><span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">Nat.succ_le_succ</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">zero_le</span> </pre></div> </div> <p>Another strategy is to use the tactic <code class="docutils literal notranslate"><span class="pre">interval_cases</span></code>,
-
@@ -741,10 +742,10 @@ which automatically splits the goal into cases whenthe variable in question is contained in an interval of natural numbers or integers. Remember that you can hover over it to see its documentation.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">m</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">(</span><span class="n">h0</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">≠</span> <span class="mi">0</span><span class="o">)</span> <span class="o">(</span><span class="n">h1</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">≠</span> <span class="mi">1</span><span class="o">)</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">≤</span> <span class="n">m</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">by_contra</span> <span class="n">h</span> <span class="n">push_neg</span> <span class="n">at</span> <span class="n">h</span> <span class="n">interval_cases</span> <span class="n">m</span> <span class="bp"><;></span> <span class="n">contradiction</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">m</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h0</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">by_contra</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">push_neg</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">interval_cases</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">contradiction</span> </pre></div> </div> <p id="index-0">Recall that the semicolon after <code class="docutils literal notranslate"><span class="pre">interval_cases</span> <span class="pre">m</span></code> means
-
@@ -754,12 +755,12 @@ to find a decision procedure to solve the problem.Lean knows that you can decide the truth value of a statement that begins with a bounded quantifier <code class="docutils literal notranslate"><span class="pre">∀</span> <span class="pre">x,</span> <span class="pre">x</span> <span class="pre"><</span> <span class="pre">n</span> <span class="pre">→</span> <span class="pre">...</span></code> or <code class="docutils literal notranslate"><span class="pre">∃</span> <span class="pre">x,</span> <span class="pre">x</span> <span class="pre"><</span> <span class="pre">n</span> <span class="pre">∧</span> <span class="pre">...</span></code> by deciding each of the finitely many instances.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">m</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">(</span><span class="n">h0</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">≠</span> <span class="mi">0</span><span class="o">)</span> <span class="o">(</span><span class="n">h1</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">≠</span> <span class="mi">1</span><span class="o">)</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">≤</span> <span class="n">m</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">by_contra</span> <span class="n">h</span> <span class="n">push_neg</span> <span class="n">at</span> <span class="n">h</span> <span class="n">revert</span> <span class="n">h0</span> <span class="n">h1</span> <span class="n">revert</span> <span class="n">h</span> <span class="n">m</span> <span class="n">decide</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">m</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h0</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">by_contra</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">push_neg</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">revert</span><span class="w"> </span><span class="n">h0</span><span class="w"> </span><span class="n">h1</span> <span class="w"> </span><span class="n">revert</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="n">m</span> <span class="w"> </span><span class="n">decide</span> </pre></div> </div> <p>With the theorem <code class="docutils literal notranslate"><span class="pre">two_le</span></code> in hand, let’s start by showing that every
-
@@ -784,44 +785,44 @@ then by one of the characterizations of what it means to be a prime number,it has a nontrivial factor, <span class="math notranslate nohighlight">\(m\)</span>, and we can apply the inductive hypothesis to that. Step through the next proof to see how that plays out.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">exists_prime_factor</span> <span class="o">{</span><span class="n">n</span> <span class="o">:</span> <span class="n">Nat</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">≤</span> <span class="n">n</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">p</span> <span class="o">:</span> <span class="n">Nat</span><span class="o">,</span> <span class="n">p.Prime</span> <span class="bp">∧</span> <span class="n">p</span> <span class="bp">∣</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">by_cases</span> <span class="n">np</span> <span class="o">:</span> <span class="n">n.Prime</span> <span class="bp">·</span> <span class="n">use</span> <span class="n">n</span><span class="o">,</span> <span class="n">np</span> <span class="n">induction'</span> <span class="n">n</span> <span class="n">using</span> <span class="n">Nat.strong_induction_on</span> <span class="k">with</span> <span class="n">n</span> <span class="n">ih</span> <span class="n">rw</span> <span class="o">[</span><span class="n">Nat.prime_def_lt</span><span class="o">]</span> <span class="n">at</span> <span class="n">np</span> <span class="n">push_neg</span> <span class="n">at</span> <span class="n">np</span> <span class="n">rcases</span> <span class="n">np</span> <span class="n">h</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">m</span><span class="o">,</span> <span class="n">mltn</span><span class="o">,</span> <span class="n">mdvdn</span><span class="o">,</span> <span class="n">mne1</span><span class="o">⟩</span> <span class="k">have</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">≠</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">mz</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mz</span><span class="o">,</span> <span class="n">zero_dvd_iff</span><span class="o">]</span> <span class="n">at</span> <span class="n">mdvdn</span> <span class="n">linarith</span> <span class="k">have</span> <span class="n">mgt2</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">≤</span> <span class="n">m</span> <span class="o">:=</span> <span class="n">two_le</span> <span class="n">this</span> <span class="n">mne1</span> <span class="n">by_cases</span> <span class="n">mp</span> <span class="o">:</span> <span class="n">m.Prime</span> <span class="bp">·</span> <span class="n">use</span> <span class="n">m</span><span class="o">,</span> <span class="n">mp</span> <span class="bp">·</span> <span class="n">rcases</span> <span class="n">ih</span> <span class="n">m</span> <span class="n">mltn</span> <span class="n">mgt2</span> <span class="n">mp</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">p</span><span class="o">,</span> <span class="n">pp</span><span class="o">,</span> <span class="n">pdvd</span><span class="o">⟩</span> <span class="n">use</span> <span class="n">p</span><span class="o">,</span> <span class="n">pp</span> <span class="n">apply</span> <span class="n">pdvd.trans</span> <span class="n">mdvdn</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">exists_prime_factor</span><span class="w"> </span><span class="o">{</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat</span><span class="o">,</span><span class="w"> </span><span class="n">p.Prime</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">by_cases</span><span class="w"> </span><span class="n">np</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">n.Prime</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">np</span> <span class="w"> </span><span class="n">induction'</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">using</span><span class="w"> </span><span class="n">Nat.strong_induction_on</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">ih</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">Nat.prime_def_lt</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">np</span> <span class="w"> </span><span class="n">push_neg</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">np</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">np</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">m</span><span class="o">,</span><span class="w"> </span><span class="n">mltn</span><span class="o">,</span><span class="w"> </span><span class="n">mdvdn</span><span class="o">,</span><span class="w"> </span><span class="n">mne1</span><span class="o">⟩</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">mz</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mz</span><span class="o">,</span><span class="w"> </span><span class="n">zero_dvd_iff</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">mdvdn</span> <span class="w"> </span><span class="n">linarith</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">mgt2</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">two_le</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="n">mne1</span> <span class="w"> </span><span class="n">by_cases</span><span class="w"> </span><span class="n">mp</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m.Prime</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">m</span><span class="o">,</span><span class="w"> </span><span class="n">mp</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">ih</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">mltn</span><span class="w"> </span><span class="n">mgt2</span><span class="w"> </span><span class="n">mp</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">p</span><span class="o">,</span><span class="w"> </span><span class="n">pp</span><span class="o">,</span><span class="w"> </span><span class="n">pdvd</span><span class="o">⟩</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">p</span><span class="o">,</span><span class="w"> </span><span class="n">pp</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">pdvd.trans</span><span class="w"> </span><span class="n">mdvdn</span> </pre></div> </div> <p>We can now prove the following formulation of our theorem. See if you can fill out the sketch. You can use <code class="docutils literal notranslate"><span class="pre">Nat.factorial_pos</span></code>, <code class="docutils literal notranslate"><span class="pre">Nat.dvd_factorial</span></code>, and <code class="docutils literal notranslate"><span class="pre">Nat.dvd_sub'</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">primes_infinite</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">n</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">p</span> <span class="bp">></span> <span class="n">n</span><span class="o">,</span> <span class="n">Nat.Prime</span> <span class="n">p</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">n</span> <span class="k">have</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">≤</span> <span class="n">Nat.factorial</span> <span class="o">(</span><span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">)</span> <span class="bp">+</span> <span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="n">rcases</span> <span class="n">exists_prime_factor</span> <span class="n">this</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">p</span><span class="o">,</span> <span class="n">pp</span><span class="o">,</span> <span class="n">pdvd</span><span class="o">⟩</span> <span class="n">refine</span> <span class="o">⟨</span><span class="n">p</span><span class="o">,</span> <span class="bp">?</span><span class="n">_</span><span class="o">,</span> <span class="n">pp</span><span class="o">⟩</span> <span class="k">show</span> <span class="n">p</span> <span class="bp">></span> <span class="n">n</span> <span class="n">by_contra</span> <span class="n">ple</span> <span class="n">push_neg</span> <span class="n">at</span> <span class="n">ple</span> <span class="k">have</span> <span class="o">:</span> <span class="n">p</span> <span class="bp">∣</span> <span class="n">Nat.factorial</span> <span class="o">(</span><span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="o">:</span> <span class="n">p</span> <span class="bp">∣</span> <span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">show</span> <span class="n">False</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">primes_infinite</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">Nat.Prime</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">n</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">Nat.factorial</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">exists_prime_factor</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">p</span><span class="o">,</span><span class="w"> </span><span class="n">pp</span><span class="o">,</span><span class="w"> </span><span class="n">pdvd</span><span class="o">⟩</span> <span class="w"> </span><span class="n">refine</span><span class="w"> </span><span class="o">⟨</span><span class="n">p</span><span class="o">,</span><span class="w"> </span><span class="bp">?</span><span class="n">_</span><span class="o">,</span><span class="w"> </span><span class="n">pp</span><span class="o">⟩</span> <span class="w"> </span><span class="k">show</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">n</span> <span class="w"> </span><span class="n">by_contra</span><span class="w"> </span><span class="n">ple</span> <span class="w"> </span><span class="n">push_neg</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">ple</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">Nat.factorial</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">show</span><span class="w"> </span><span class="n">False</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Let’s consider a variation of the proof above, where instead
-
@@ -850,31 +851,31 @@ <code class="docutils literal notranslate"><span class="pre">Finset.subset_iff</span></code>, <code class="docutils literal notranslate"><span class="pre">Finset.mem_union</span></code>, <code class="docutils literal notranslate"><span class="pre">Finset.mem_inter</span></code>,and <code class="docutils literal notranslate"><span class="pre">Finset.mem_sdiff</span></code>. The <code class="docutils literal notranslate"><span class="pre">ext</span></code> tactic can still be used to show that two finite sets are equal by showing that every element of one is an element of the other.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">Finset</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">Finset</span> <span class="kn">section</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">DecidableEq</span> <span class="n">α</span><span class="o">]</span> <span class="o">(</span><span class="n">r</span> <span class="n">s</span> <span class="n">t</span> <span class="o">:</span> <span class="n">Finset</span> <span class="n">α</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">DecidableEq</span><span class="w"> </span><span class="n">α</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Finset</span><span class="w"> </span><span class="n">α</span><span class="o">)</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">r</span> <span class="bp">∩</span> <span class="o">(</span><span class="n">s</span> <span class="bp">∪</span> <span class="n">t</span><span class="o">)</span> <span class="bp">⊆</span> <span class="n">r</span> <span class="bp">∩</span> <span class="n">s</span> <span class="bp">∪</span> <span class="n">r</span> <span class="bp">∩</span> <span class="n">t</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">subset_iff</span><span class="o">]</span> <span class="n">intro</span> <span class="n">x</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mem_inter</span><span class="o">,</span> <span class="n">mem_union</span><span class="o">,</span> <span class="n">mem_union</span><span class="o">,</span> <span class="n">mem_inter</span><span class="o">,</span> <span class="n">mem_inter</span><span class="o">]</span> <span class="n">tauto</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">subset_iff</span><span class="o">]</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mem_inter</span><span class="o">,</span><span class="w"> </span><span class="n">mem_union</span><span class="o">,</span><span class="w"> </span><span class="n">mem_union</span><span class="o">,</span><span class="w"> </span><span class="n">mem_inter</span><span class="o">,</span><span class="w"> </span><span class="n">mem_inter</span><span class="o">]</span> <span class="w"> </span><span class="n">tauto</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">r</span> <span class="bp">∩</span> <span class="o">(</span><span class="n">s</span> <span class="bp">∪</span> <span class="n">t</span><span class="o">)</span> <span class="bp">⊆</span> <span class="n">r</span> <span class="bp">∩</span> <span class="n">s</span> <span class="bp">∪</span> <span class="n">r</span> <span class="bp">∩</span> <span class="n">t</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="o">[</span><span class="n">subset_iff</span><span class="o">]</span> <span class="n">intro</span> <span class="n">x</span> <span class="n">tauto</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">subset_iff</span><span class="o">]</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="n">tauto</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">r</span> <span class="bp">∩</span> <span class="n">s</span> <span class="bp">∪</span> <span class="n">r</span> <span class="bp">∩</span> <span class="n">t</span> <span class="bp">⊆</span> <span class="n">r</span> <span class="bp">∩</span> <span class="o">(</span><span class="n">s</span> <span class="bp">∪</span> <span class="n">t</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="o">[</span><span class="n">subset_iff</span><span class="o">]</span> <span class="n">intro</span> <span class="n">x</span> <span class="n">tauto</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">subset_iff</span><span class="o">]</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="n">tauto</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">r</span> <span class="bp">∩</span> <span class="n">s</span> <span class="bp">∪</span> <span class="n">r</span> <span class="bp">∩</span> <span class="n">t</span> <span class="bp">=</span> <span class="n">r</span> <span class="bp">∩</span> <span class="o">(</span><span class="n">s</span> <span class="bp">∪</span> <span class="n">t</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ext</span> <span class="n">x</span> <span class="n">simp</span> <span class="n">tauto</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="n">tauto</span> <span class="kd">end</span> </pre></div>
-
@@ -883,27 +884,27 @@ <p>We have used a new trick: the <code class="docutils literal notranslate"><span class="pre">tauto</span></code> tactic (and a strengthenedversion, <code class="docutils literal notranslate"><span class="pre">tauto!</span></code>, which uses classical logic) can be used to dispense with propositional tautologies. See if you can use these methods to prove the two examples below.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">r</span> <span class="bp">∪</span> <span class="n">s</span><span class="o">)</span> <span class="bp">∩</span> <span class="o">(</span><span class="n">r</span> <span class="bp">∪</span> <span class="n">t</span><span class="o">)</span> <span class="bp">=</span> <span class="n">r</span> <span class="bp">∪</span> <span class="n">s</span> <span class="bp">∩</span> <span class="n">t</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">r</span> <span class="bp">\</span> <span class="n">s</span><span class="o">)</span> <span class="bp">\</span> <span class="n">t</span> <span class="bp">=</span> <span class="n">r</span> <span class="bp">\</span> <span class="o">(</span><span class="n">s</span> <span class="bp">∪</span> <span class="n">t</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="bp">\</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="bp">\</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">\</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>The theorem <code class="docutils literal notranslate"><span class="pre">Finset.dvd_prod_of_mem</span></code> tells us that if an <code class="docutils literal notranslate"><span class="pre">n</span></code> is an element of a finite set <code class="docutils literal notranslate"><span class="pre">s</span></code>, then <code class="docutils literal notranslate"><span class="pre">n</span></code> divides <code class="docutils literal notranslate"><span class="pre">∏</span> <span class="pre">i</span> <span class="pre">in</span> <span class="pre">s,</span> <span class="pre">i</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">s</span> <span class="o">:</span> <span class="n">Finset</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">n</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">)</span> <span class="o">:</span> <span class="n">n</span> <span class="bp">∣</span> <span class="bp">∏</span> <span class="n">i</span> <span class="k">in</span> <span class="n">s</span><span class="o">,</span> <span class="n">i</span> <span class="o">:=</span> <span class="n">Finset.dvd_prod_of_mem</span> <span class="n">_</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Finset</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="bp">∏</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Finset.dvd_prod_of_mem</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>We also need to know that the converse holds in the case where <code class="docutils literal notranslate"><span class="pre">n</span></code> is prime and <code class="docutils literal notranslate"><span class="pre">s</span></code> is a set of primes. To show that, we need the following lemma, which you should be able to prove using the theorem <code class="docutils literal notranslate"><span class="pre">Nat.Prime.eq_one_or_self_of_dvd</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">_root_.Nat.Prime.eq_of_dvd_of_prime</span> <span class="o">{</span><span class="n">p</span> <span class="n">q</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">(</span><span class="n">prime_p</span> <span class="o">:</span> <span class="n">Nat.Prime</span> <span class="n">p</span><span class="o">)</span> <span class="o">(</span><span class="n">prime_q</span> <span class="o">:</span> <span class="n">Nat.Prime</span> <span class="n">q</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">p</span> <span class="bp">∣</span> <span class="n">q</span><span class="o">)</span> <span class="o">:</span> <span class="n">p</span> <span class="bp">=</span> <span class="n">q</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">_root_.Nat.Prime.eq_of_dvd_of_prime</span><span class="w"> </span><span class="o">{</span><span class="n">p</span><span class="w"> </span><span class="n">q</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span> <span class="w"> </span><span class="o">(</span><span class="n">prime_p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat.Prime</span><span class="w"> </span><span class="n">p</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">prime_q</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat.Prime</span><span class="w"> </span><span class="n">q</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">q</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">q</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>We can use this lemma to show that if a prime <code class="docutils literal notranslate"><span class="pre">p</span></code> divides a product of a finite
-
@@ -922,15 +923,15 @@ the relevant rewrite rules for the product.In the proof below, the first <code class="docutils literal notranslate"><span class="pre">simp</span></code> applies <code class="docutils literal notranslate"><span class="pre">Finset.prod_empty</span></code>. Step through the beginning of the proof to see the induction unfold, and then finish it off.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">mem_of_dvd_prod_primes</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">Finset</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">{</span><span class="n">p</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">(</span><span class="n">prime_p</span> <span class="o">:</span> <span class="n">p.Prime</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="bp">∀</span> <span class="n">n</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="n">Nat.Prime</span> <span class="n">n</span><span class="o">)</span> <span class="bp">→</span> <span class="o">(</span><span class="n">p</span> <span class="bp">∣</span> <span class="bp">∏</span> <span class="n">n</span> <span class="k">in</span> <span class="n">s</span><span class="o">,</span> <span class="n">n</span><span class="o">)</span> <span class="bp">→</span> <span class="n">p</span> <span class="bp">∈</span> <span class="n">s</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">h₀</span> <span class="n">h₁</span> <span class="n">induction'</span> <span class="n">s</span> <span class="n">using</span> <span class="n">Finset.induction_on</span> <span class="k">with</span> <span class="n">a</span> <span class="n">s</span> <span class="n">ans</span> <span class="n">ih</span> <span class="bp">·</span> <span class="n">simp</span> <span class="n">at</span> <span class="n">h₁</span> <span class="n">linarith</span> <span class="o">[</span><span class="n">prime_p.two_le</span><span class="o">]</span> <span class="n">simp</span> <span class="o">[</span><span class="n">Finset.prod_insert</span> <span class="n">ans</span><span class="o">,</span> <span class="n">prime_p.dvd_mul</span><span class="o">]</span> <span class="n">at</span> <span class="n">h₀</span> <span class="n">h₁</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mem_insert</span><span class="o">]</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">mem_of_dvd_prod_primes</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Finset</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">prime_p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">p.Prime</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="o">(</span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">Nat.Prime</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="o">(</span><span class="n">p</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="bp">∏</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span> <span class="w"> </span><span class="n">induction'</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">using</span><span class="w"> </span><span class="n">Finset.induction_on</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">ans</span><span class="w"> </span><span class="n">ih</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">h₁</span> <span class="w"> </span><span class="n">linarith</span><span class="w"> </span><span class="o">[</span><span class="n">prime_p.two_le</span><span class="o">]</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">Finset.prod_insert</span><span class="w"> </span><span class="n">ans</span><span class="o">,</span><span class="w"> </span><span class="n">prime_p.dvd_mul</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">h₀</span><span class="w"> </span><span class="n">h₁</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mem_insert</span><span class="o">]</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>We need one last property of finite sets.
-
@@ -940,8 +941,8 @@ we wrote <code class="docutils literal notranslate"><span class="pre">{</span> <span class="pre">x</span> <span class="pre">∈</span> <span class="pre">s</span> <span class="pre">|</span> <span class="pre">P</span> <span class="pre">x</span> <span class="pre">}</span></code> for the set ofelements of <code class="docutils literal notranslate"><span class="pre">s</span></code> that satisfy <code class="docutils literal notranslate"><span class="pre">P</span></code>. Given <code class="docutils literal notranslate"><span class="pre">s</span> <span class="pre">:</span> <span class="pre">Finset</span> <span class="pre">α</span></code>, the analogous notion is written <code class="docutils literal notranslate"><span class="pre">s.filter</span> <span class="pre">P</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">s</span> <span class="o">:</span> <span class="n">Finset</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">s.filter</span> <span class="n">Nat.Prime</span> <span class="bp">↔</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">s</span> <span class="bp">∧</span> <span class="n">x.Prime</span> <span class="o">:=</span> <span class="n">mem_filter</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Finset</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s.filter</span><span class="w"> </span><span class="n">Nat.Prime</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x.Prime</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">mem_filter</span> </pre></div> </div> <p>We now prove an alternative formulation of the statement that there are infinitely many
-
@@ -954,25 +955,25 @@ of the resultleads to the contradiction we are looking for. See if you can complete the sketch below. You can use <code class="docutils literal notranslate"><span class="pre">Finset.prod_pos</span></code> in the proof of the first <code class="docutils literal notranslate"><span class="pre">have</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">primes_infinite'</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">s</span> <span class="o">:</span> <span class="n">Finset</span> <span class="n">Nat</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">p</span><span class="o">,</span> <span class="n">Nat.Prime</span> <span class="n">p</span> <span class="bp">∧</span> <span class="n">p</span> <span class="bp">∉</span> <span class="n">s</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">s</span> <span class="n">by_contra</span> <span class="n">h</span> <span class="n">push_neg</span> <span class="n">at</span> <span class="n">h</span> <span class="n">set</span> <span class="n">s'</span> <span class="o">:=</span> <span class="n">s.filter</span> <span class="n">Nat.Prime</span> <span class="k">with</span> <span class="n">s'_def</span> <span class="k">have</span> <span class="n">mem_s'</span> <span class="o">:</span> <span class="bp">∀</span> <span class="o">{</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">},</span> <span class="n">n</span> <span class="bp">∈</span> <span class="n">s'</span> <span class="bp">↔</span> <span class="n">n.Prime</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">n</span> <span class="n">simp</span> <span class="o">[</span><span class="n">s'_def</span><span class="o">]</span> <span class="n">apply</span> <span class="n">h</span> <span class="k">have</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">≤</span> <span class="o">(</span><span class="bp">∏</span> <span class="n">i</span> <span class="k">in</span> <span class="n">s'</span><span class="o">,</span> <span class="n">i</span><span class="o">)</span> <span class="bp">+</span> <span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="n">rcases</span> <span class="n">exists_prime_factor</span> <span class="n">this</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">p</span><span class="o">,</span> <span class="n">pp</span><span class="o">,</span> <span class="n">pdvd</span><span class="o">⟩</span> <span class="k">have</span> <span class="o">:</span> <span class="n">p</span> <span class="bp">∣</span> <span class="bp">∏</span> <span class="n">i</span> <span class="k">in</span> <span class="n">s'</span><span class="o">,</span> <span class="n">i</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="o">:</span> <span class="n">p</span> <span class="bp">∣</span> <span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">convert</span> <span class="n">Nat.dvd_sub'</span> <span class="n">pdvd</span> <span class="n">this</span> <span class="n">simp</span> <span class="k">show</span> <span class="n">False</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">primes_infinite'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Finset</span><span class="w"> </span><span class="n">Nat</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">p</span><span class="o">,</span><span class="w"> </span><span class="n">Nat.Prime</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">∉</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">s</span> <span class="w"> </span><span class="n">by_contra</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">push_neg</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">set</span><span class="w"> </span><span class="n">s'</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">s.filter</span><span class="w"> </span><span class="n">Nat.Prime</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">s'_def</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">mem_s'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">{</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">},</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s'</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">n.Prime</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">n</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">s'_def</span><span class="o">]</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="o">(</span><span class="bp">∏</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">s'</span><span class="o">,</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">exists_prime_factor</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">p</span><span class="o">,</span><span class="w"> </span><span class="n">pp</span><span class="o">,</span><span class="w"> </span><span class="n">pdvd</span><span class="o">⟩</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="bp">∏</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">s'</span><span class="o">,</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">convert</span><span class="w"> </span><span class="n">Nat.dvd_sub'</span><span class="w"> </span><span class="n">pdvd</span><span class="w"> </span><span class="n">this</span> <span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="k">show</span><span class="w"> </span><span class="n">False</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>We have thus seen two ways of saying that there are infinitely many primes:
-
@@ -988,22 +989,22 @@ <p>In Mathlib, <code class="docutils literal notranslate"><span class="pre">Finset.sup</span> <span class="pre">s</span> <span class="pre">f</span></code> denotes the supremum of the values of <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">x</span></code> as <code class="docutils literal notranslate"><span class="pre">x</span></code>ranges over <code class="docutils literal notranslate"><span class="pre">s</span></code>, returning <code class="docutils literal notranslate"><span class="pre">0</span></code> in the case where <code class="docutils literal notranslate"><span class="pre">s</span></code> is empty and the codomain of <code class="docutils literal notranslate"><span class="pre">f</span></code> is <code class="docutils literal notranslate"><span class="pre">ℕ</span></code>. In the first proof, we use <code class="docutils literal notranslate"><span class="pre">s.sup</span> <span class="pre">id</span></code>, where <code class="docutils literal notranslate"><span class="pre">id</span></code> is the identity function, to refer to the maximum value in <code class="docutils literal notranslate"><span class="pre">s</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">bounded_of_ex_finset</span> <span class="o">(</span><span class="n">Q</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="kt">Prop</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="bp">∃</span> <span class="n">s</span> <span class="o">:</span> <span class="n">Finset</span> <span class="n">ℕ</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">k</span><span class="o">,</span> <span class="n">Q</span> <span class="n">k</span> <span class="bp">→</span> <span class="n">k</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">)</span> <span class="bp">→</span> <span class="bp">∃</span> <span class="n">n</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">k</span><span class="o">,</span> <span class="n">Q</span> <span class="n">k</span> <span class="bp">→</span> <span class="n">k</span> <span class="bp"><</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rintro</span> <span class="o">⟨</span><span class="n">s</span><span class="o">,</span> <span class="n">hs</span><span class="o">⟩</span> <span class="n">use</span> <span class="n">s.sup</span> <span class="n">id</span> <span class="bp">+</span> <span class="mi">1</span> <span class="n">intro</span> <span class="n">k</span> <span class="n">Qk</span> <span class="n">apply</span> <span class="n">Nat.lt_succ_of_le</span> <span class="k">show</span> <span class="n">id</span> <span class="n">k</span> <span class="bp">≤</span> <span class="n">s.sup</span> <span class="n">id</span> <span class="n">apply</span> <span class="n">le_sup</span> <span class="o">(</span><span class="n">hs</span> <span class="n">k</span> <span class="n">Qk</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">bounded_of_ex_finset</span><span class="w"> </span><span class="o">(</span><span class="n">Q</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="kt">Prop</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="o">(</span><span class="bp">∃</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Finset</span><span class="w"> </span><span class="n">ℕ</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">k</span><span class="o">,</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">k</span><span class="o">,</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="o">⟨</span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">hs</span><span class="o">⟩</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">s.sup</span><span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="n">Qk</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">Nat.lt_succ_of_le</span> <span class="w"> </span><span class="k">show</span><span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">s.sup</span><span class="w"> </span><span class="n">id</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">le_sup</span><span class="w"> </span><span class="o">(</span><span class="n">hs</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="n">Qk</span><span class="o">)</span> <span class="kd">theorem</span> <span class="n">ex_finset_of_bounded</span> <span class="o">(</span><span class="n">Q</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="kt">Prop</span><span class="o">)</span> <span class="o">[</span><span class="n">DecidablePred</span> <span class="n">Q</span><span class="o">]</span> <span class="o">:</span> <span class="o">(</span><span class="bp">∃</span> <span class="n">n</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">k</span><span class="o">,</span> <span class="n">Q</span> <span class="n">k</span> <span class="bp">→</span> <span class="n">k</span> <span class="bp">≤</span> <span class="n">n</span><span class="o">)</span> <span class="bp">→</span> <span class="bp">∃</span> <span class="n">s</span> <span class="o">:</span> <span class="n">Finset</span> <span class="n">ℕ</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">k</span><span class="o">,</span> <span class="n">Q</span> <span class="n">k</span> <span class="bp">↔</span> <span class="n">k</span> <span class="bp">∈</span> <span class="n">s</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rintro</span> <span class="o">⟨</span><span class="n">n</span><span class="o">,</span> <span class="n">hn</span><span class="o">⟩</span> <span class="n">use</span> <span class="o">(</span><span class="n">range</span> <span class="o">(</span><span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">))</span><span class="bp">.</span><span class="n">filter</span> <span class="n">Q</span> <span class="n">intro</span> <span class="n">k</span> <span class="n">simp</span> <span class="o">[</span><span class="n">Nat.lt_succ_iff</span><span class="o">]</span> <span class="n">exact</span> <span class="n">hn</span> <span class="n">k</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">ex_finset_of_bounded</span><span class="w"> </span><span class="o">(</span><span class="n">Q</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="kt">Prop</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">DecidablePred</span><span class="w"> </span><span class="n">Q</span><span class="o">]</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="o">(</span><span class="bp">∃</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">k</span><span class="o">,</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Finset</span><span class="w"> </span><span class="n">ℕ</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">k</span><span class="o">,</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="o">⟨</span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">hn</span><span class="o">⟩</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="o">(</span><span class="n">range</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">))</span><span class="bp">.</span><span class="n">filter</span><span class="w"> </span><span class="n">Q</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">k</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">Nat.lt_succ_iff</span><span class="o">]</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">hn</span><span class="w"> </span><span class="n">k</span> </pre></div> </div> <p>A small variation on our second proof that there are infinitely many primes
-
@@ -1033,7 +1034,7 @@ But in that case, <span class="math notranslate nohighlight">\(p\)</span> divides <span class="math notranslate nohighlight">\(4 \prod_{i = 2}^k p_i\)</span>and hence 3, which contradicts the fact that it is not 3.</p> <p>In Lean, the notation <code class="docutils literal notranslate"><span class="pre">n</span> <span class="pre">%</span> <span class="pre">m</span></code>, read “<code class="docutils literal notranslate"><span class="pre">n</span></code> modulo <code class="docutils literal notranslate"><span class="pre">m</span></code>,” denotes the remainder of the division of <code class="docutils literal notranslate"><span class="pre">n</span></code> by <code class="docutils literal notranslate"><span class="pre">m</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="mi">27</span> <span class="bp">%</span> <span class="mi">4</span> <span class="bp">=</span> <span class="mi">3</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">norm_num</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">27</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span> </pre></div> </div> <p>We can then render the statement “<code class="docutils literal notranslate"><span class="pre">n</span></code> is congruent to 3 modulo 4”
-
@@ -1044,66 +1045,66 @@ a small number of cases.In the second named theorem, remember that the semicolon means that the subsequent tactic block is applied to all the goals created by the preceding tactic.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="mi">4</span> <span class="bp">*</span> <span class="n">n</span> <span class="bp">+</span> <span class="mi">3</span><span class="o">)</span> <span class="bp">%</span> <span class="mi">4</span> <span class="bp">=</span> <span class="mi">3</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">add_comm</span><span class="o">,</span> <span class="n">Nat.add_mul_mod_self_left</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="mi">4</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">3</span><span class="o">)</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">add_comm</span><span class="o">,</span><span class="w"> </span><span class="n">Nat.add_mul_mod_self_left</span><span class="o">]</span> <span class="kd">theorem</span> <span class="n">mod_4_eq_3_or_mod_4_eq_3</span> <span class="o">{</span><span class="n">m</span> <span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">*</span> <span class="n">n</span> <span class="bp">%</span> <span class="mi">4</span> <span class="bp">=</span> <span class="mi">3</span><span class="o">)</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">%</span> <span class="mi">4</span> <span class="bp">=</span> <span class="mi">3</span> <span class="bp">∨</span> <span class="n">n</span> <span class="bp">%</span> <span class="mi">4</span> <span class="bp">=</span> <span class="mi">3</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">revert</span> <span class="n">h</span> <span class="n">rw</span> <span class="o">[</span><span class="n">Nat.mul_mod</span><span class="o">]</span> <span class="k">have</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">%</span> <span class="mi">4</span> <span class="bp"><</span> <span class="mi">4</span> <span class="o">:=</span> <span class="n">Nat.mod_lt</span> <span class="n">m</span> <span class="o">(</span><span class="kd">by</span> <span class="n">norm_num</span><span class="o">)</span> <span class="n">interval_cases</span> <span class="n">m</span> <span class="bp">%</span> <span class="mi">4</span> <span class="bp"><;></span> <span class="n">simp</span> <span class="o">[</span><span class="bp">-</span><span class="n">Nat.mul_mod_mod</span><span class="o">]</span> <span class="k">have</span> <span class="o">:</span> <span class="n">n</span> <span class="bp">%</span> <span class="mi">4</span> <span class="bp"><</span> <span class="mi">4</span> <span class="o">:=</span> <span class="n">Nat.mod_lt</span> <span class="n">n</span> <span class="o">(</span><span class="kd">by</span> <span class="n">norm_num</span><span class="o">)</span> <span class="n">interval_cases</span> <span class="n">n</span> <span class="bp">%</span> <span class="mi">4</span> <span class="bp"><;></span> <span class="n">simp</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">mod_4_eq_3_or_mod_4_eq_3</span><span class="w"> </span><span class="o">{</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">3</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">revert</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">Nat.mul_mod</span><span class="o">]</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Nat.mod_lt</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">(</span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span><span class="o">)</span> <span class="w"> </span><span class="n">interval_cases</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="bp">-</span><span class="n">Nat.mul_mod_mod</span><span class="o">]</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Nat.mod_lt</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">(</span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span><span class="o">)</span> <span class="w"> </span><span class="n">interval_cases</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">simp</span> <span class="kd">theorem</span> <span class="n">two_le_of_mod_4_eq_3</span> <span class="o">{</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">n</span> <span class="bp">%</span> <span class="mi">4</span> <span class="bp">=</span> <span class="mi">3</span><span class="o">)</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">≤</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">two_le</span> <span class="bp"><;></span> <span class="bp">·</span> <span class="n">intro</span> <span class="n">neq</span> <span class="n">rw</span> <span class="o">[</span><span class="n">neq</span><span class="o">]</span> <span class="n">at</span> <span class="n">h</span> <span class="n">norm_num</span> <span class="n">at</span> <span class="n">h</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">two_le_of_mod_4_eq_3</span><span class="w"> </span><span class="o">{</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">3</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">two_le</span><span class="w"> </span><span class="bp"><;></span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">neq</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">neq</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">norm_num</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>We will also need the following fact, which says that if <code class="docutils literal notranslate"><span class="pre">m</span></code> is a nontrivial divisor of <code class="docutils literal notranslate"><span class="pre">n</span></code>, then so is <code class="docutils literal notranslate"><span class="pre">n</span> <span class="pre">/</span> <span class="pre">m</span></code>. See if you can complete the proof using <code class="docutils literal notranslate"><span class="pre">Nat.div_dvd_of_dvd</span></code> and <code class="docutils literal notranslate"><span class="pre">Nat.div_lt_self</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">aux</span> <span class="o">{</span><span class="n">m</span> <span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">(</span><span class="n">h₀</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">∣</span> <span class="n">n</span><span class="o">)</span> <span class="o">(</span><span class="n">h₁</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">≤</span> <span class="n">m</span><span class="o">)</span> <span class="o">(</span><span class="n">h₂</span> <span class="o">:</span> <span class="n">m</span> <span class="bp"><</span> <span class="n">n</span><span class="o">)</span> <span class="o">:</span> <span class="n">n</span> <span class="bp">/</span> <span class="n">m</span> <span class="bp">∣</span> <span class="n">n</span> <span class="bp">∧</span> <span class="n">n</span> <span class="bp">/</span> <span class="n">m</span> <span class="bp"><</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">aux</span><span class="w"> </span><span class="o">{</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">m</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h₂</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Now put all the pieces together to prove that any number congruent to 3 modulo 4 has a prime divisor with that same property.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">exists_prime_factor_mod_4_eq_3</span> <span class="o">{</span><span class="n">n</span> <span class="o">:</span> <span class="n">Nat</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">n</span> <span class="bp">%</span> <span class="mi">4</span> <span class="bp">=</span> <span class="mi">3</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">p</span> <span class="o">:</span> <span class="n">Nat</span><span class="o">,</span> <span class="n">p.Prime</span> <span class="bp">∧</span> <span class="n">p</span> <span class="bp">∣</span> <span class="n">n</span> <span class="bp">∧</span> <span class="n">p</span> <span class="bp">%</span> <span class="mi">4</span> <span class="bp">=</span> <span class="mi">3</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">by_cases</span> <span class="n">np</span> <span class="o">:</span> <span class="n">n.Prime</span> <span class="bp">·</span> <span class="n">use</span> <span class="n">n</span> <span class="n">induction'</span> <span class="n">n</span> <span class="n">using</span> <span class="n">Nat.strong_induction_on</span> <span class="k">with</span> <span class="n">n</span> <span class="n">ih</span> <span class="n">rw</span> <span class="o">[</span><span class="n">Nat.prime_def_lt</span><span class="o">]</span> <span class="n">at</span> <span class="n">np</span> <span class="n">push_neg</span> <span class="n">at</span> <span class="n">np</span> <span class="n">rcases</span> <span class="n">np</span> <span class="o">(</span><span class="n">two_le_of_mod_4_eq_3</span> <span class="n">h</span><span class="o">)</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">m</span><span class="o">,</span> <span class="n">mltn</span><span class="o">,</span> <span class="n">mdvdn</span><span class="o">,</span> <span class="n">mne1</span><span class="o">⟩</span> <span class="k">have</span> <span class="n">mge2</span> <span class="o">:</span> <span class="mi">2</span> <span class="bp">≤</span> <span class="n">m</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">two_le</span> <span class="n">_</span> <span class="n">mne1</span> <span class="n">intro</span> <span class="n">mz</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mz</span><span class="o">,</span> <span class="n">zero_dvd_iff</span><span class="o">]</span> <span class="n">at</span> <span class="n">mdvdn</span> <span class="n">linarith</span> <span class="k">have</span> <span class="n">neq</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">*</span> <span class="o">(</span><span class="n">n</span> <span class="bp">/</span> <span class="n">m</span><span class="o">)</span> <span class="bp">=</span> <span class="n">n</span> <span class="o">:=</span> <span class="n">Nat.mul_div_cancel'</span> <span class="n">mdvdn</span> <span class="k">have</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">%</span> <span class="mi">4</span> <span class="bp">=</span> <span class="mi">3</span> <span class="bp">∨</span> <span class="n">n</span> <span class="bp">/</span> <span class="n">m</span> <span class="bp">%</span> <span class="mi">4</span> <span class="bp">=</span> <span class="mi">3</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">mod_4_eq_3_or_mod_4_eq_3</span> <span class="n">rw</span> <span class="o">[</span><span class="n">neq</span><span class="o">,</span> <span class="n">h</span><span class="o">]</span> <span class="n">rcases</span> <span class="n">this</span> <span class="k">with</span> <span class="n">h1</span> <span class="bp">|</span> <span class="n">h1</span> <span class="bp">.</span> <span class="gr">sorry</span> <span class="bp">.</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">exists_prime_factor_mod_4_eq_3</span><span class="w"> </span><span class="o">{</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">3</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat</span><span class="o">,</span><span class="w"> </span><span class="n">p.Prime</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">by_cases</span><span class="w"> </span><span class="n">np</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">n.Prime</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">n</span> <span class="w"> </span><span class="n">induction'</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">using</span><span class="w"> </span><span class="n">Nat.strong_induction_on</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">ih</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">Nat.prime_def_lt</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">np</span> <span class="w"> </span><span class="n">push_neg</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">np</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">np</span><span class="w"> </span><span class="o">(</span><span class="n">two_le_of_mod_4_eq_3</span><span class="w"> </span><span class="n">h</span><span class="o">)</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">m</span><span class="o">,</span><span class="w"> </span><span class="n">mltn</span><span class="o">,</span><span class="w"> </span><span class="n">mdvdn</span><span class="o">,</span><span class="w"> </span><span class="n">mne1</span><span class="o">⟩</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">mge2</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">two_le</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">mne1</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">mz</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mz</span><span class="o">,</span><span class="w"> </span><span class="n">zero_dvd_iff</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">mdvdn</span> <span class="w"> </span><span class="n">linarith</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">neq</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="n">m</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Nat.mul_div_cancel'</span><span class="w"> </span><span class="n">mdvdn</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">mod_4_eq_3_or_mod_4_eq_3</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">neq</span><span class="o">,</span><span class="w"> </span><span class="n">h</span><span class="o">]</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">h1</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">h1</span> <span class="w"> </span><span class="bp">.</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="bp">.</span><span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>We are in the home stretch. Given a set <code class="docutils literal notranslate"><span class="pre">s</span></code> of prime numbers, we need to talk about the result of removing 3 from that set, if it is present. The function <code class="docutils literal notranslate"><span class="pre">Finset.erase</span></code> handles that.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">m</span> <span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">s</span> <span class="o">:</span> <span class="n">Finset</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">∈</span> <span class="n">erase</span> <span class="n">s</span> <span class="n">n</span><span class="o">)</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">≠</span> <span class="n">n</span> <span class="bp">∧</span> <span class="n">m</span> <span class="bp">∈</span> <span class="n">s</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rwa</span> <span class="o">[</span><span class="n">mem_erase</span><span class="o">]</span> <span class="n">at</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Finset</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">erase</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rwa</span><span class="w"> </span><span class="o">[</span><span class="n">mem_erase</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">h</span> <span class="kd">example</span> <span class="o">(</span><span class="n">m</span> <span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">s</span> <span class="o">:</span> <span class="n">Finset</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">∈</span> <span class="n">erase</span> <span class="n">s</span> <span class="n">n</span><span class="o">)</span> <span class="o">:</span> <span class="n">m</span> <span class="bp">≠</span> <span class="n">n</span> <span class="bp">∧</span> <span class="n">m</span> <span class="bp">∈</span> <span class="n">s</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="n">at</span> <span class="n">h</span> <span class="n">assumption</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Finset</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">erase</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">assumption</span> </pre></div> </div> <p>We are now ready to prove that there are infinitely many primes
-
@@ -1111,31 +1112,31 @@ congruent to 3 modulo 4.Fill in the missing parts below. Our solution uses <code class="docutils literal notranslate"><span class="pre">Nat.dvd_add_iff_left</span></code> and <code class="docutils literal notranslate"><span class="pre">Nat.dvd_sub'</span></code> along the way.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">primes_mod_4_eq_3_infinite</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">n</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">p</span> <span class="bp">></span> <span class="n">n</span><span class="o">,</span> <span class="n">Nat.Prime</span> <span class="n">p</span> <span class="bp">∧</span> <span class="n">p</span> <span class="bp">%</span> <span class="mi">4</span> <span class="bp">=</span> <span class="mi">3</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">by_contra</span> <span class="n">h</span> <span class="n">push_neg</span> <span class="n">at</span> <span class="n">h</span> <span class="n">rcases</span> <span class="n">h</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">n</span><span class="o">,</span> <span class="n">hn</span><span class="o">⟩</span> <span class="k">have</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">s</span> <span class="o">:</span> <span class="n">Finset</span> <span class="n">Nat</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">p</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">,</span> <span class="n">p.Prime</span> <span class="bp">∧</span> <span class="n">p</span> <span class="bp">%</span> <span class="mi">4</span> <span class="bp">=</span> <span class="mi">3</span> <span class="bp">↔</span> <span class="n">p</span> <span class="bp">∈</span> <span class="n">s</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">ex_finset_of_bounded</span> <span class="n">use</span> <span class="n">n</span> <span class="n">contrapose</span><span class="bp">!</span> <span class="n">hn</span> <span class="n">rcases</span> <span class="n">hn</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">p</span><span class="o">,</span> <span class="o">⟨</span><span class="n">pp</span><span class="o">,</span> <span class="n">p4</span><span class="o">⟩,</span> <span class="n">pltn</span><span class="o">⟩</span> <span class="n">exact</span> <span class="o">⟨</span><span class="n">p</span><span class="o">,</span> <span class="n">pltn</span><span class="o">,</span> <span class="n">pp</span><span class="o">,</span> <span class="n">p4</span><span class="o">⟩</span> <span class="n">rcases</span> <span class="n">this</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">s</span><span class="o">,</span> <span class="n">hs</span><span class="o">⟩</span> <span class="k">have</span> <span class="n">h₁</span> <span class="o">:</span> <span class="o">((</span><span class="mi">4</span> <span class="bp">*</span> <span class="bp">∏</span> <span class="n">i</span> <span class="k">in</span> <span class="n">erase</span> <span class="n">s</span> <span class="mi">3</span><span class="o">,</span> <span class="n">i</span><span class="o">)</span> <span class="bp">+</span> <span class="mi">3</span><span class="o">)</span> <span class="bp">%</span> <span class="mi">4</span> <span class="bp">=</span> <span class="mi">3</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="n">rcases</span> <span class="n">exists_prime_factor_mod_4_eq_3</span> <span class="n">h₁</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">p</span><span class="o">,</span> <span class="n">pp</span><span class="o">,</span> <span class="n">pdvd</span><span class="o">,</span> <span class="n">p4eq</span><span class="o">⟩</span> <span class="k">have</span> <span class="n">ps</span> <span class="o">:</span> <span class="n">p</span> <span class="bp">∈</span> <span class="n">s</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="n">pne3</span> <span class="o">:</span> <span class="n">p</span> <span class="bp">≠</span> <span class="mi">3</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="o">:</span> <span class="n">p</span> <span class="bp">∣</span> <span class="mi">4</span> <span class="bp">*</span> <span class="bp">∏</span> <span class="n">i</span> <span class="k">in</span> <span class="n">erase</span> <span class="n">s</span> <span class="mi">3</span><span class="o">,</span> <span class="n">i</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="o">:</span> <span class="n">p</span> <span class="bp">∣</span> <span class="mi">3</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="o">:</span> <span class="n">p</span> <span class="bp">=</span> <span class="mi">3</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="n">contradiction</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">primes_mod_4_eq_3_infinite</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">Nat.Prime</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">by_contra</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">push_neg</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">hn</span><span class="o">⟩</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Finset</span><span class="w"> </span><span class="n">Nat</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">,</span><span class="w"> </span><span class="n">p.Prime</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">ex_finset_of_bounded</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">n</span> <span class="w"> </span><span class="n">contrapose</span><span class="bp">!</span><span class="w"> </span><span class="n">hn</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">hn</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">p</span><span class="o">,</span><span class="w"> </span><span class="o">⟨</span><span class="n">pp</span><span class="o">,</span><span class="w"> </span><span class="n">p4</span><span class="o">⟩,</span><span class="w"> </span><span class="n">pltn</span><span class="o">⟩</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="o">⟨</span><span class="n">p</span><span class="o">,</span><span class="w"> </span><span class="n">pltn</span><span class="o">,</span><span class="w"> </span><span class="n">pp</span><span class="o">,</span><span class="w"> </span><span class="n">p4</span><span class="o">⟩</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">hs</span><span class="o">⟩</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">((</span><span class="mi">4</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="bp">∏</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">erase</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">3</span><span class="o">)</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">exists_prime_factor_mod_4_eq_3</span><span class="w"> </span><span class="n">h₁</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">p</span><span class="o">,</span><span class="w"> </span><span class="n">pp</span><span class="o">,</span><span class="w"> </span><span class="n">pdvd</span><span class="o">,</span><span class="w"> </span><span class="n">p4eq</span><span class="o">⟩</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">ps</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">pne3</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="bp">∏</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">erase</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">contradiction</span> </pre></div> </div> <p>If you managed to complete the proof, congratulations! This has been a serious
-
-
-
@@ -1,3 +1,5 @@<!DOCTYPE html> <html class="writer-html5" lang="en" data-content_root="./"> <head>
-
@@ -6,18 +8,17 @@<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>6. Structures — Mathematics in Lean 0.1 documentation</title> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=80d5e7a1" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=86f27845" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" /> <link rel="stylesheet" type="text/css" href="_static/css/custom.css?v=0731ccc3" /> <link rel="shortcut icon" href="_static/favicon.ico"/> <script src="_static/jquery.js?v=8dae8fb0"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=888ff710"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> <script src="_static/jquery.js?v=5d32c60e"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=9bcbadda"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> <script src="_static/js/theme.js"></script> <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" />
-
@@ -120,34 +121,34 @@ An <em>instance</em> of the structure is a particular bundle of data satisfyingthe constraints. For example, we can specify that a point is a tuple of three real numbers:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">@[</span><span class="n">ext</span><span class="kd">]</span> <span class="kd">structure</span> <span class="n">Point</span> <span class="n">where</span> <span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="n">z</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="kd">structure</span><span class="w"> </span><span class="n">Point</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span> <span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span> <span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span> </pre></div> </div> <p>The <code class="docutils literal notranslate"><span class="pre">@[ext]</span></code> annotation tells Lean to automatically generate theorems that can be used to prove that two instances of a structure are equal when their components are equal, a property known as <em>extensionality</em>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="n">Point.ext</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="n">Point.ext</span> <span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">Point</span><span class="o">)</span> <span class="o">(</span><span class="n">hx</span> <span class="o">:</span> <span class="n">a.x</span> <span class="bp">=</span> <span class="n">b.x</span><span class="o">)</span> <span class="o">(</span><span class="n">hy</span> <span class="o">:</span> <span class="n">a.y</span> <span class="bp">=</span> <span class="n">b.y</span><span class="o">)</span> <span class="o">(</span><span class="n">hz</span> <span class="o">:</span> <span class="n">a.z</span> <span class="bp">=</span> <span class="n">b.z</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">=</span> <span class="n">b</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ext</span> <span class="n">repeat'</span> <span class="n">assumption</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hx</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a.x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b.x</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hy</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a.y</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b.y</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hz</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a.z</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b.z</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">ext</span> <span class="w"> </span><span class="n">repeat'</span><span class="w"> </span><span class="n">assumption</span> </pre></div> </div> <p>We can then define particular instances of the <code class="docutils literal notranslate"><span class="pre">Point</span></code> structure. Lean provides multiple ways of doing that.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">myPoint1</span> <span class="o">:</span> <span class="n">Point</span> <span class="n">where</span> <span class="n">x</span> <span class="o">:=</span> <span class="mi">2</span> <span class="n">y</span> <span class="o">:=</span> <span class="bp">-</span><span class="mi">1</span> <span class="n">z</span> <span class="o">:=</span> <span class="mi">4</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">myPoint1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">2</span> <span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="bp">-</span><span class="mi">1</span> <span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">4</span> <span class="kd">def</span> <span class="n">myPoint2</span> <span class="o">:</span> <span class="n">Point</span> <span class="o">:=</span> <span class="o">⟨</span><span class="mi">2</span><span class="o">,</span> <span class="bp">-</span><span class="mi">1</span><span class="o">,</span> <span class="mi">4</span><span class="o">⟩</span> <span class="kd">def</span><span class="w"> </span><span class="n">myPoint2</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">⟨</span><span class="mi">2</span><span class="o">,</span><span class="w"> </span><span class="bp">-</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="o">⟩</span> <span class="kd">def</span> <span class="n">myPoint3</span> <span class="o">:=</span> <span class="n">Point.mk</span> <span class="mi">2</span> <span class="o">(</span><span class="bp">-</span><span class="mi">1</span><span class="o">)</span> <span class="mi">4</span> <span class="kd">def</span><span class="w"> </span><span class="n">myPoint3</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Point.mk</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">(</span><span class="bp">-</span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="mi">4</span> </pre></div> </div> <p>In the first example, the fields of the structure are named
-
@@ -156,12 +157,12 @@ The function <code class="docutils literal notranslate"><span class="pre">Point.mk</span></code> referred to in the definition of <code class="docutils literal notranslate"><span class="pre">myPoint3</span></code>is known as the <em>constructor</em> for the <code class="docutils literal notranslate"><span class="pre">Point</span></code> structure, because it serves to construct elements. You can specify a different name if you want, like <code class="docutils literal notranslate"><span class="pre">build</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">structure</span> <span class="n">Point'</span> <span class="n">where</span> <span class="n">build</span> <span class="o">::</span> <span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="n">z</span> <span class="o">:</span> <span class="n">ℝ</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">structure</span><span class="w"> </span><span class="n">Point'</span><span class="w"> </span><span class="n">where</span><span class="w"> </span><span class="n">build</span><span class="w"> </span><span class="o">::</span> <span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span> <span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span> <span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span> <span class="k">#check</span> <span class="n">Point'.build</span> <span class="mi">2</span> <span class="o">(</span><span class="bp">-</span><span class="mi">1</span><span class="o">)</span> <span class="mi">4</span> <span class="k">#check</span><span class="w"> </span><span class="n">Point'.build</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">(</span><span class="bp">-</span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="mi">4</span> </pre></div> </div> <p>The next two examples show how to define functions on structures.
-
@@ -179,23 +180,23 @@ But remember that it is often convenient to useanonymous projection notation, which allows us to write <code class="docutils literal notranslate"><span class="pre">a.add</span> <span class="pre">b</span></code> instead of <code class="docutils literal notranslate"><span class="pre">Point.add</span> <span class="pre">a</span> <span class="pre">b</span></code>. Lean interprets the former as the latter because <code class="docutils literal notranslate"><span class="pre">a</span></code> has type <code class="docutils literal notranslate"><span class="pre">Point</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">namespace</span> <span class="n">Point</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">namespace</span><span class="w"> </span><span class="n">Point</span> <span class="kd">def</span> <span class="n">add</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">Point</span><span class="o">)</span> <span class="o">:</span> <span class="n">Point</span> <span class="o">:=</span> <span class="o">⟨</span><span class="n">a.x</span> <span class="bp">+</span> <span class="n">b.x</span><span class="o">,</span> <span class="n">a.y</span> <span class="bp">+</span> <span class="n">b.y</span><span class="o">,</span> <span class="n">a.z</span> <span class="bp">+</span> <span class="n">b.z</span><span class="o">⟩</span> <span class="kd">def</span><span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">⟨</span><span class="n">a.x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b.x</span><span class="o">,</span><span class="w"> </span><span class="n">a.y</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b.y</span><span class="o">,</span><span class="w"> </span><span class="n">a.z</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b.z</span><span class="o">⟩</span> <span class="kd">def</span> <span class="n">add'</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">Point</span><span class="o">)</span> <span class="o">:</span> <span class="n">Point</span> <span class="n">where</span> <span class="n">x</span> <span class="o">:=</span> <span class="n">a.x</span> <span class="bp">+</span> <span class="n">b.x</span> <span class="n">y</span> <span class="o">:=</span> <span class="n">a.y</span> <span class="bp">+</span> <span class="n">b.y</span> <span class="n">z</span> <span class="o">:=</span> <span class="n">a.z</span> <span class="bp">+</span> <span class="n">b.z</span> <span class="kd">def</span><span class="w"> </span><span class="n">add'</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">a.x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b.x</span> <span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">a.y</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b.y</span> <span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">a.z</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b.z</span> <span class="k">#check</span> <span class="n">add</span> <span class="n">myPoint1</span> <span class="n">myPoint2</span> <span class="k">#check</span> <span class="n">myPoint1.add</span> <span class="n">myPoint2</span> <span class="k">#check</span><span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="n">myPoint1</span><span class="w"> </span><span class="n">myPoint2</span> <span class="k">#check</span><span class="w"> </span><span class="n">myPoint1.add</span><span class="w"> </span><span class="n">myPoint2</span> <span class="kd">end</span> <span class="n">Point</span> <span class="kd">end</span><span class="w"> </span><span class="n">Point</span> <span class="k">#check</span> <span class="n">Point.add</span> <span class="n">myPoint1</span> <span class="n">myPoint2</span> <span class="k">#check</span> <span class="n">myPoint1.add</span> <span class="n">myPoint2</span> <span class="k">#check</span><span class="w"> </span><span class="n">Point.add</span><span class="w"> </span><span class="n">myPoint1</span><span class="w"> </span><span class="n">myPoint2</span> <span class="k">#check</span><span class="w"> </span><span class="n">myPoint1.add</span><span class="w"> </span><span class="n">myPoint2</span> </pre></div> </div> <p>Below we will continue to put definitions in the relevant
-
@@ -208,18 +209,18 @@ Below we use the <code class="docutils literal notranslate"><span class="pre">protected</span></code> keyword so that the name of thetheorem is <code class="docutils literal notranslate"><span class="pre">Point.add_comm</span></code>, even when the namespace is open. This is helpful when we want to avoid ambiguity with a generic theorem like <code class="docutils literal notranslate"><span class="pre">add_comm</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">protected</span> <span class="kd">theorem</span> <span class="n">add_comm</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">Point</span><span class="o">)</span> <span class="o">:</span> <span class="n">add</span> <span class="n">a</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">add</span> <span class="n">b</span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">add</span><span class="o">,</span> <span class="n">add</span><span class="o">]</span> <span class="n">ext</span> <span class="bp"><;></span> <span class="n">dsimp</span> <span class="n">repeat'</span> <span class="n">apply</span> <span class="n">add_comm</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">protected</span><span class="w"> </span><span class="kd">theorem</span><span class="w"> </span><span class="n">add_comm</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">add</span><span class="o">,</span><span class="w"> </span><span class="n">add</span><span class="o">]</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">dsimp</span> <span class="w"> </span><span class="n">repeat'</span><span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">add_comm</span> <span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">Point</span><span class="o">)</span> <span class="o">:</span> <span class="n">add</span> <span class="n">a</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">add</span> <span class="n">b</span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="o">[</span><span class="n">add</span><span class="o">,</span> <span class="n">add_comm</span><span class="o">]</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">add</span><span class="o">,</span><span class="w"> </span><span class="n">add_comm</span><span class="o">]</span> </pre></div> </div> <p>Because Lean can unfold definitions and simplify projections internally, sometimes the equations we want hold definitionally.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">add_x</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">Point</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">a.add</span> <span class="n">b</span><span class="o">)</span><span class="bp">.</span><span class="n">x</span> <span class="bp">=</span> <span class="n">a.x</span> <span class="bp">+</span> <span class="n">b.x</span> <span class="o">:=</span> <span class="n">rfl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">add_x</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">a.add</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="bp">.</span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a.x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b.x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> </pre></div> </div> <p>It is also possible to define functions on structures using
-
@@ -232,20 +233,20 @@ in the second.Although it is sometimes convenient to define functions this way, and structural eta-reduction makes this alternative definitionally equivalent, it can make things less convenient in later proofs. In particular, <code class="docutils literal notranslate"><span class="pre">rw</span> <span class="pre">[addAlt]</span></code> leaves us with a messier goal view containing a <code class="docutils literal notranslate"><span class="pre">match</span></code> statement.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">addAlt</span> <span class="o">:</span> <span class="n">Point</span> <span class="bp">→</span> <span class="n">Point</span> <span class="bp">→</span> <span class="n">Point</span> <span class="bp">|</span> <span class="n">Point.mk</span> <span class="n">x₁</span> <span class="n">y₁</span> <span class="n">z₁</span><span class="o">,</span> <span class="n">Point.mk</span> <span class="n">x₂</span> <span class="n">y₂</span> <span class="n">z₂</span> <span class="bp">=></span> <span class="o">⟨</span><span class="n">x₁</span> <span class="bp">+</span> <span class="n">x₂</span><span class="o">,</span> <span class="n">y₁</span> <span class="bp">+</span> <span class="n">y₂</span><span class="o">,</span> <span class="n">z₁</span> <span class="bp">+</span> <span class="n">z₂</span><span class="o">⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">addAlt</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Point</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Point</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">Point.mk</span><span class="w"> </span><span class="n">x₁</span><span class="w"> </span><span class="n">y₁</span><span class="w"> </span><span class="n">z₁</span><span class="o">,</span><span class="w"> </span><span class="n">Point.mk</span><span class="w"> </span><span class="n">x₂</span><span class="w"> </span><span class="n">y₂</span><span class="w"> </span><span class="n">z₂</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="o">⟨</span><span class="n">x₁</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">x₂</span><span class="o">,</span><span class="w"> </span><span class="n">y₁</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y₂</span><span class="o">,</span><span class="w"> </span><span class="n">z₁</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">z₂</span><span class="o">⟩</span> <span class="kd">def</span> <span class="n">addAlt'</span> <span class="o">:</span> <span class="n">Point</span> <span class="bp">→</span> <span class="n">Point</span> <span class="bp">→</span> <span class="n">Point</span> <span class="bp">|</span> <span class="o">⟨</span><span class="n">x₁</span><span class="o">,</span> <span class="n">y₁</span><span class="o">,</span> <span class="n">z₁</span><span class="o">⟩,</span> <span class="o">⟨</span><span class="n">x₂</span><span class="o">,</span> <span class="n">y₂</span><span class="o">,</span> <span class="n">z₂</span><span class="o">⟩</span> <span class="bp">=></span> <span class="o">⟨</span><span class="n">x₁</span> <span class="bp">+</span> <span class="n">x₂</span><span class="o">,</span> <span class="n">y₁</span> <span class="bp">+</span> <span class="n">y₂</span><span class="o">,</span> <span class="n">z₁</span> <span class="bp">+</span> <span class="n">z₂</span><span class="o">⟩</span> <span class="kd">def</span><span class="w"> </span><span class="n">addAlt'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Point</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Point</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="o">⟨</span><span class="n">x₁</span><span class="o">,</span><span class="w"> </span><span class="n">y₁</span><span class="o">,</span><span class="w"> </span><span class="n">z₁</span><span class="o">⟩,</span><span class="w"> </span><span class="o">⟨</span><span class="n">x₂</span><span class="o">,</span><span class="w"> </span><span class="n">y₂</span><span class="o">,</span><span class="w"> </span><span class="n">z₂</span><span class="o">⟩</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="o">⟨</span><span class="n">x₁</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">x₂</span><span class="o">,</span><span class="w"> </span><span class="n">y₁</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y₂</span><span class="o">,</span><span class="w"> </span><span class="n">z₁</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">z₂</span><span class="o">⟩</span> <span class="kd">theorem</span> <span class="n">addAlt_x</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">Point</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">a.addAlt</span> <span class="n">b</span><span class="o">)</span><span class="bp">.</span><span class="n">x</span> <span class="bp">=</span> <span class="n">a.x</span> <span class="bp">+</span> <span class="n">b.x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rfl</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">addAlt_x</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">a.addAlt</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="bp">.</span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a.x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b.x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">theorem</span> <span class="n">addAlt_comm</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">Point</span><span class="o">)</span> <span class="o">:</span> <span class="n">addAlt</span> <span class="n">a</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">addAlt</span> <span class="n">b</span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">addAlt</span><span class="o">,</span> <span class="n">addAlt</span><span class="o">]</span> <span class="c1">-- the same proof still works, but the goal view here is harder to read</span> <span class="n">ext</span> <span class="bp"><;></span> <span class="n">dsimp</span> <span class="n">repeat'</span> <span class="n">apply</span> <span class="n">add_comm</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">addAlt_comm</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">addAlt</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">addAlt</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">addAlt</span><span class="o">,</span><span class="w"> </span><span class="n">addAlt</span><span class="o">]</span> <span class="w"> </span><span class="c1">-- the same proof still works, but the goal view here is harder to read</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">dsimp</span> <span class="w"> </span><span class="n">repeat'</span><span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">add_comm</span> </pre></div> </div> <p>Mathematical constructions often involve taking apart bundled information and
-
@@ -255,15 +256,15 @@ of doing this efficiently.As an exercise, try proving that <code class="docutils literal notranslate"><span class="pre">Point.add</span></code> is associative. Then define scalar multiplication for a point and show that it distributes over addition.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">protected</span> <span class="kd">theorem</span> <span class="n">add_assoc</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">Point</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">a.add</span> <span class="n">b</span><span class="o">)</span><span class="bp">.</span><span class="n">add</span> <span class="n">c</span> <span class="bp">=</span> <span class="n">a.add</span> <span class="o">(</span><span class="n">b.add</span> <span class="n">c</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">protected</span><span class="w"> </span><span class="kd">theorem</span><span class="w"> </span><span class="n">add_assoc</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">a.add</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="bp">.</span><span class="n">add</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a.add</span><span class="w"> </span><span class="o">(</span><span class="n">b.add</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">def</span> <span class="n">smul</span> <span class="o">(</span><span class="n">r</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">Point</span><span class="o">)</span> <span class="o">:</span> <span class="n">Point</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">def</span><span class="w"> </span><span class="n">smul</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">theorem</span> <span class="n">smul_distrib</span> <span class="o">(</span><span class="n">r</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">Point</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">smul</span> <span class="n">r</span> <span class="n">a</span><span class="o">)</span><span class="bp">.</span><span class="n">add</span> <span class="o">(</span><span class="n">smul</span> <span class="n">r</span> <span class="n">b</span><span class="o">)</span> <span class="bp">=</span> <span class="n">smul</span> <span class="n">r</span> <span class="o">(</span><span class="n">a.add</span> <span class="n">b</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">smul_distrib</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="o">(</span><span class="n">smul</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="bp">.</span><span class="n">add</span><span class="w"> </span><span class="o">(</span><span class="n">smul</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">smul</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="o">(</span><span class="n">a.add</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Using structures is only the first step on the road to
-
@@ -287,44 +288,44 @@ the equilateral triangle in three-space with vertices<span class="math notranslate nohighlight">\((1, 0, 0)\)</span>, <span class="math notranslate nohighlight">\((0, 1, 0)\)</span>, and <span class="math notranslate nohighlight">\((0, 0, 1)\)</span>, together with its interior. We can represent it in Lean as follows:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">structure</span> <span class="n">StandardTwoSimplex</span> <span class="n">where</span> <span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="n">z</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="n">x_nonneg</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">x</span> <span class="n">y_nonneg</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">y</span> <span class="n">z_nonneg</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">z</span> <span class="n">sum_eq</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">y</span> <span class="bp">+</span> <span class="n">z</span> <span class="bp">=</span> <span class="mi">1</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">structure</span><span class="w"> </span><span class="n">StandardTwoSimplex</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span> <span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span> <span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span> <span class="w"> </span><span class="n">x_nonneg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="n">y_nonneg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">y</span> <span class="w"> </span><span class="n">z_nonneg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">z</span> <span class="w"> </span><span class="n">sum_eq</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span> </pre></div> </div> <p>Notice that the last four fields refer to <code class="docutils literal notranslate"><span class="pre">x</span></code>, <code class="docutils literal notranslate"><span class="pre">y</span></code>, and <code class="docutils literal notranslate"><span class="pre">z</span></code>, that is, the first three fields. We can define a map from the two-simplex to itself that swaps <code class="docutils literal notranslate"><span class="pre">x</span></code> and <code class="docutils literal notranslate"><span class="pre">y</span></code>:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">swapXy</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">StandardTwoSimplex</span><span class="o">)</span> <span class="o">:</span> <span class="n">StandardTwoSimplex</span> <span class="n">where</span> <span class="n">x</span> <span class="o">:=</span> <span class="n">a.y</span> <span class="n">y</span> <span class="o">:=</span> <span class="n">a.x</span> <span class="n">z</span> <span class="o">:=</span> <span class="n">a.z</span> <span class="n">x_nonneg</span> <span class="o">:=</span> <span class="n">a.y_nonneg</span> <span class="n">y_nonneg</span> <span class="o">:=</span> <span class="n">a.x_nonneg</span> <span class="n">z_nonneg</span> <span class="o">:=</span> <span class="n">a.z_nonneg</span> <span class="n">sum_eq</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">add_comm</span> <span class="n">a.y</span> <span class="n">a.x</span><span class="o">,</span> <span class="n">a.sum_eq</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">swapXy</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">StandardTwoSimplex</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">StandardTwoSimplex</span> <span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">a.y</span> <span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">a.x</span> <span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">a.z</span> <span class="w"> </span><span class="n">x_nonneg</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">a.y_nonneg</span> <span class="w"> </span><span class="n">y_nonneg</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">a.x_nonneg</span> <span class="w"> </span><span class="n">z_nonneg</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">a.z_nonneg</span> <span class="w"> </span><span class="n">sum_eq</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">add_comm</span><span class="w"> </span><span class="n">a.y</span><span class="w"> </span><span class="n">a.x</span><span class="o">,</span><span class="w"> </span><span class="n">a.sum_eq</span><span class="o">]</span> </pre></div> </div> <p>More interestingly, we can compute the midpoint of two points on the simplex. We have added the phrase <code class="docutils literal notranslate"><span class="pre">noncomputable</span> <span class="pre">section</span></code> at the beginning of this file in order to use division on the real numbers.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">noncomputable</span> <span class="kn">section</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">noncomputable</span><span class="w"> </span><span class="kn">section</span> <span class="kd">def</span> <span class="n">midpoint</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">StandardTwoSimplex</span><span class="o">)</span> <span class="o">:</span> <span class="n">StandardTwoSimplex</span> <span class="n">where</span> <span class="n">x</span> <span class="o">:=</span> <span class="o">(</span><span class="n">a.x</span> <span class="bp">+</span> <span class="n">b.x</span><span class="o">)</span> <span class="bp">/</span> <span class="mi">2</span> <span class="n">y</span> <span class="o">:=</span> <span class="o">(</span><span class="n">a.y</span> <span class="bp">+</span> <span class="n">b.y</span><span class="o">)</span> <span class="bp">/</span> <span class="mi">2</span> <span class="n">z</span> <span class="o">:=</span> <span class="o">(</span><span class="n">a.z</span> <span class="bp">+</span> <span class="n">b.z</span><span class="o">)</span> <span class="bp">/</span> <span class="mi">2</span> <span class="n">x_nonneg</span> <span class="o">:=</span> <span class="n">div_nonneg</span> <span class="o">(</span><span class="n">add_nonneg</span> <span class="n">a.x_nonneg</span> <span class="n">b.x_nonneg</span><span class="o">)</span> <span class="o">(</span><span class="kd">by</span> <span class="n">norm_num</span><span class="o">)</span> <span class="n">y_nonneg</span> <span class="o">:=</span> <span class="n">div_nonneg</span> <span class="o">(</span><span class="n">add_nonneg</span> <span class="n">a.y_nonneg</span> <span class="n">b.y_nonneg</span><span class="o">)</span> <span class="o">(</span><span class="kd">by</span> <span class="n">norm_num</span><span class="o">)</span> <span class="n">z_nonneg</span> <span class="o">:=</span> <span class="n">div_nonneg</span> <span class="o">(</span><span class="n">add_nonneg</span> <span class="n">a.z_nonneg</span> <span class="n">b.z_nonneg</span><span class="o">)</span> <span class="o">(</span><span class="kd">by</span> <span class="n">norm_num</span><span class="o">)</span> <span class="n">sum_eq</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">field_simp</span><span class="bp">;</span> <span class="n">linarith</span> <span class="o">[</span><span class="n">a.sum_eq</span><span class="o">,</span> <span class="n">b.sum_eq</span><span class="o">]</span> <span class="kd">def</span><span class="w"> </span><span class="n">midpoint</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">StandardTwoSimplex</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">StandardTwoSimplex</span> <span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="n">a.x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b.x</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span> <span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="n">a.y</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b.y</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span> <span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="n">a.z</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b.z</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span> <span class="w"> </span><span class="n">x_nonneg</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">div_nonneg</span><span class="w"> </span><span class="o">(</span><span class="n">add_nonneg</span><span class="w"> </span><span class="n">a.x_nonneg</span><span class="w"> </span><span class="n">b.x_nonneg</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span><span class="o">)</span> <span class="w"> </span><span class="n">y_nonneg</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">div_nonneg</span><span class="w"> </span><span class="o">(</span><span class="n">add_nonneg</span><span class="w"> </span><span class="n">a.y_nonneg</span><span class="w"> </span><span class="n">b.y_nonneg</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span><span class="o">)</span> <span class="w"> </span><span class="n">z_nonneg</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">div_nonneg</span><span class="w"> </span><span class="o">(</span><span class="n">add_nonneg</span><span class="w"> </span><span class="n">a.z_nonneg</span><span class="w"> </span><span class="n">b.z_nonneg</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="kd">by</span><span class="w"> </span><span class="n">norm_num</span><span class="o">)</span> <span class="w"> </span><span class="n">sum_eq</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">field_simp</span><span class="bp">;</span><span class="w"> </span><span class="n">linarith</span><span class="w"> </span><span class="o">[</span><span class="n">a.sum_eq</span><span class="o">,</span><span class="w"> </span><span class="n">b.sum_eq</span><span class="o">]</span> </pre></div> </div> <p>Here we have established <code class="docutils literal notranslate"><span class="pre">x_nonneg</span></code>, <code class="docutils literal notranslate"><span class="pre">y_nonneg</span></code>, and <code class="docutils literal notranslate"><span class="pre">z_nonneg</span></code>
-
@@ -335,9 +336,9 @@ we can take the weighted average <span class="math notranslate nohighlight">\(\lambda a + (1 - \lambda) b\)</span>of two points <span class="math notranslate nohighlight">\(a\)</span> and <span class="math notranslate nohighlight">\(b\)</span> in the standard 2-simplex. We challenge you to define that function, in analogy to the <code class="docutils literal notranslate"><span class="pre">midpoint</span></code> function above.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">weightedAverage</span> <span class="o">(</span><span class="n">lambda</span> <span class="o">:</span> <span class="n">Real</span><span class="o">)</span> <span class="o">(</span><span class="n">lambda_nonneg</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">lambda</span><span class="o">)</span> <span class="o">(</span><span class="n">lambda_le</span> <span class="o">:</span> <span class="n">lambda</span> <span class="bp">≤</span> <span class="mi">1</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">StandardTwoSimplex</span><span class="o">)</span> <span class="o">:</span> <span class="n">StandardTwoSimplex</span> <span class="o">:=</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">weightedAverage</span><span class="w"> </span><span class="o">(</span><span class="n">lambda</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Real</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">lambda_nonneg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">lambda</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">lambda_le</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">lambda</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">StandardTwoSimplex</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">StandardTwoSimplex</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Structures can depend on parameters.
-
@@ -346,29 +347,29 @@ <span class="math notranslate nohighlight">\(n\)</span>-simplex for any <span class="math notranslate nohighlight">\(n\)</span>.At this stage, you don’t have to know anything about the type <code class="docutils literal notranslate"><span class="pre">Fin</span> <span class="pre">n</span></code> except that it has <span class="math notranslate nohighlight">\(n\)</span> elements, and that Lean knows how to sum over it.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">BigOperators</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">BigOperators</span> <span class="kd">structure</span> <span class="n">StandardSimplex</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="n">where</span> <span class="n">V</span> <span class="o">:</span> <span class="n">Fin</span> <span class="n">n</span> <span class="bp">→</span> <span class="n">ℝ</span> <span class="n">NonNeg</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">i</span> <span class="o">:</span> <span class="n">Fin</span> <span class="n">n</span><span class="o">,</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">V</span> <span class="n">i</span> <span class="n">sum_eq_one</span> <span class="o">:</span> <span class="o">(</span><span class="bp">∑</span> <span class="n">i</span><span class="o">,</span> <span class="n">V</span> <span class="n">i</span><span class="o">)</span> <span class="bp">=</span> <span class="mi">1</span> <span class="kd">structure</span><span class="w"> </span><span class="n">StandardSimplex</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Fin</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span> <span class="w"> </span><span class="n">NonNeg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Fin</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">i</span> <span class="w"> </span><span class="n">sum_eq_one</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">∑</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span> <span class="kn">namespace</span> <span class="n">StandardSimplex</span> <span class="kn">namespace</span><span class="w"> </span><span class="n">StandardSimplex</span> <span class="kd">def</span> <span class="n">midpoint</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">StandardSimplex</span> <span class="n">n</span><span class="o">)</span> <span class="o">:</span> <span class="n">StandardSimplex</span> <span class="n">n</span> <span class="n">where</span> <span class="n">V</span> <span class="n">i</span> <span class="o">:=</span> <span class="o">(</span><span class="n">a.V</span> <span class="n">i</span> <span class="bp">+</span> <span class="n">b.V</span> <span class="n">i</span><span class="o">)</span> <span class="bp">/</span> <span class="mi">2</span> <span class="n">NonNeg</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">i</span> <span class="n">apply</span> <span class="n">div_nonneg</span> <span class="bp">·</span> <span class="n">linarith</span> <span class="o">[</span><span class="n">a.NonNeg</span> <span class="n">i</span><span class="o">,</span> <span class="n">b.NonNeg</span> <span class="n">i</span><span class="o">]</span> <span class="n">norm_num</span> <span class="n">sum_eq_one</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="o">[</span><span class="n">div_eq_mul_inv</span><span class="o">,</span> <span class="bp">←</span> <span class="n">Finset.sum_mul</span><span class="o">,</span> <span class="n">Finset.sum_add_distrib</span><span class="o">,</span> <span class="n">a.sum_eq_one</span><span class="o">,</span> <span class="n">b.sum_eq_one</span><span class="o">]</span> <span class="n">field_simp</span> <span class="kd">def</span><span class="w"> </span><span class="n">midpoint</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">StandardSimplex</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">StandardSimplex</span><span class="w"> </span><span class="n">n</span> <span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="n">a.V</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b.V</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span> <span class="w"> </span><span class="n">NonNeg</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">i</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">div_nonneg</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">linarith</span><span class="w"> </span><span class="o">[</span><span class="n">a.NonNeg</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">b.NonNeg</span><span class="w"> </span><span class="n">i</span><span class="o">]</span> <span class="w"> </span><span class="n">norm_num</span> <span class="w"> </span><span class="n">sum_eq_one</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">div_eq_mul_inv</span><span class="o">,</span><span class="w"> </span><span class="bp">←</span><span class="w"> </span><span class="n">Finset.sum_mul</span><span class="o">,</span><span class="w"> </span><span class="n">Finset.sum_add_distrib</span><span class="o">,</span> <span class="w"> </span><span class="n">a.sum_eq_one</span><span class="o">,</span><span class="w"> </span><span class="n">b.sum_eq_one</span><span class="o">]</span> <span class="w"> </span><span class="n">field_simp</span> <span class="kd">end</span> <span class="n">StandardSimplex</span> <span class="kd">end</span><span class="w"> </span><span class="n">StandardSimplex</span> </pre></div> </div> <p>As an exercise, see if you can define the weighted average of
-
@@ -381,15 +382,15 @@ Interestingly, they can also be used to bundle together propertieswithout the data. For example, the next structure, <code class="docutils literal notranslate"><span class="pre">IsLinear</span></code>, bundles together the two components of linearity.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">structure</span> <span class="n">IsLinear</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="n">where</span> <span class="n">is_additive</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="n">y</span><span class="o">,</span> <span class="n">f</span> <span class="o">(</span><span class="n">x</span> <span class="bp">+</span> <span class="n">y</span><span class="o">)</span> <span class="bp">=</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">f</span> <span class="n">y</span> <span class="n">preserves_mul</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="n">c</span><span class="o">,</span> <span class="n">f</span> <span class="o">(</span><span class="n">c</span> <span class="bp">*</span> <span class="n">x</span><span class="o">)</span> <span class="bp">=</span> <span class="n">c</span> <span class="bp">*</span> <span class="n">f</span> <span class="n">x</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">structure</span><span class="w"> </span><span class="n">IsLinear</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">is_additive</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">y</span> <span class="w"> </span><span class="n">preserves_mul</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">c</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span> <span class="kn">section</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">linf</span> <span class="o">:</span> <span class="n">IsLinear</span> <span class="n">f</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">linf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsLinear</span><span class="w"> </span><span class="n">f</span><span class="o">)</span> <span class="k">#check</span> <span class="n">linf.is_additive</span> <span class="k">#check</span> <span class="n">linf.preserves_mul</span> <span class="k">#check</span><span class="w"> </span><span class="n">linf.is_additive</span> <span class="k">#check</span><span class="w"> </span><span class="n">linf.preserves_mul</span> <span class="kd">end</span> </pre></div>
-
@@ -398,11 +399,11 @@ <p>It is worth pointing out that structures are not the only way to bundletogether data. The <code class="docutils literal notranslate"><span class="pre">Point</span></code> data structure can be defined using the generic type product, and <code class="docutils literal notranslate"><span class="pre">IsLinear</span></code> can be defined with a simple <code class="docutils literal notranslate"><span class="pre">and</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">Point''</span> <span class="o">:=</span> <span class="n">ℝ</span> <span class="bp">×</span> <span class="n">ℝ</span> <span class="bp">×</span> <span class="n">ℝ</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">Point''</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">ℝ</span> <span class="kd">def</span> <span class="n">IsLinear'</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:=</span> <span class="o">(</span><span class="bp">∀</span> <span class="n">x</span> <span class="n">y</span><span class="o">,</span> <span class="n">f</span> <span class="o">(</span><span class="n">x</span> <span class="bp">+</span> <span class="n">y</span><span class="o">)</span> <span class="bp">=</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">f</span> <span class="n">y</span><span class="o">)</span> <span class="bp">∧</span> <span class="bp">∀</span> <span class="n">x</span> <span class="n">c</span><span class="o">,</span> <span class="n">f</span> <span class="o">(</span><span class="n">c</span> <span class="bp">*</span> <span class="n">x</span><span class="o">)</span> <span class="bp">=</span> <span class="n">c</span> <span class="bp">*</span> <span class="n">f</span> <span class="n">x</span> <span class="kd">def</span><span class="w"> </span><span class="n">IsLinear'</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">(</span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">c</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span> </pre></div> </div> <p>Generic type constructions can even be used in place of structures
-
@@ -415,42 +416,42 @@ Any <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">:</span> <span class="pre">PReal</span></code> has two components: the value, and the property of beingpositive. You can access these components as <code class="docutils literal notranslate"><span class="pre">x.val</span></code>, which has type <code class="docutils literal notranslate"><span class="pre">ℝ</span></code>, and <code class="docutils literal notranslate"><span class="pre">x.property</span></code>, which represents the fact <code class="docutils literal notranslate"><span class="pre">0</span> <span class="pre"><</span> <span class="pre">x.val</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">PReal</span> <span class="o">:=</span> <span class="o">{</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">//</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">y</span> <span class="o">}</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">PReal</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">//</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">}</span> <span class="kn">section</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">PReal</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">PReal</span><span class="o">)</span> <span class="k">#check</span> <span class="n">x.val</span> <span class="k">#check</span> <span class="n">x.property</span> <span class="k">#check</span> <span class="n">x.1</span> <span class="k">#check</span> <span class="n">x.2</span> <span class="k">#check</span><span class="w"> </span><span class="n">x.val</span> <span class="k">#check</span><span class="w"> </span><span class="n">x.property</span> <span class="k">#check</span><span class="w"> </span><span class="n">x</span><span class="bp">.</span><span class="mi">1</span> <span class="k">#check</span><span class="w"> </span><span class="n">x</span><span class="bp">.</span><span class="mi">2</span> <span class="kd">end</span> </pre></div> </div> <p>We could have used subtypes to define the standard 2-simplex, as well as the standard <span class="math notranslate nohighlight">\(n\)</span>-simplex for an arbitrary <span class="math notranslate nohighlight">\(n\)</span>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">StandardTwoSimplex'</span> <span class="o">:=</span> <span class="o">{</span> <span class="n">p</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">×</span> <span class="n">ℝ</span> <span class="bp">×</span> <span class="n">ℝ</span> <span class="bp">//</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">p.1</span> <span class="bp">∧</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">p.2.1</span> <span class="bp">∧</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">p.2.2</span> <span class="bp">∧</span> <span class="n">p.1</span> <span class="bp">+</span> <span class="n">p.2.1</span> <span class="bp">+</span> <span class="n">p.2.2</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">}</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">StandardTwoSimplex'</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">//</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">p</span><span class="bp">.</span><span class="mi">1</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">p</span><span class="bp">.</span><span class="mi">2</span><span class="bp">.</span><span class="mi">1</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">p</span><span class="bp">.</span><span class="mi">2</span><span class="bp">.</span><span class="mi">2</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">p</span><span class="bp">.</span><span class="mi">1</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">p</span><span class="bp">.</span><span class="mi">2</span><span class="bp">.</span><span class="mi">1</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">p</span><span class="bp">.</span><span class="mi">2</span><span class="bp">.</span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">}</span> <span class="kd">def</span> <span class="n">StandardSimplex'</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:=</span> <span class="o">{</span> <span class="n">v</span> <span class="o">:</span> <span class="n">Fin</span> <span class="n">n</span> <span class="bp">→</span> <span class="n">ℝ</span> <span class="bp">//</span> <span class="o">(</span><span class="bp">∀</span> <span class="n">i</span> <span class="o">:</span> <span class="n">Fin</span> <span class="n">n</span><span class="o">,</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">v</span> <span class="n">i</span><span class="o">)</span> <span class="bp">∧</span> <span class="o">(</span><span class="bp">∑</span> <span class="n">i</span><span class="o">,</span> <span class="n">v</span> <span class="n">i</span><span class="o">)</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">}</span> <span class="kd">def</span><span class="w"> </span><span class="n">StandardSimplex'</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Fin</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">//</span><span class="w"> </span><span class="o">(</span><span class="bp">∀</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Fin</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="o">(</span><span class="bp">∑</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">}</span> </pre></div> </div> <p>Similarly, <em>Sigma types</em> are generalizations of ordered pairs, whereby the type of the second component depends on the type of the first.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">StdSimplex</span> <span class="o">:=</span> <span class="bp">Σ</span> <span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">,</span> <span class="n">StandardSimplex</span> <span class="n">n</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">StdSimplex</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="bp">Σ</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">,</span><span class="w"> </span><span class="n">StandardSimplex</span><span class="w"> </span><span class="n">n</span> <span class="kn">section</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">s</span> <span class="o">:</span> <span class="n">StdSimplex</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">StdSimplex</span><span class="o">)</span> <span class="k">#check</span> <span class="n">s.fst</span> <span class="k">#check</span> <span class="n">s.snd</span> <span class="k">#check</span><span class="w"> </span><span class="n">s.fst</span> <span class="k">#check</span><span class="w"> </span><span class="n">s.snd</span> <span class="k">#check</span> <span class="n">s.1</span> <span class="k">#check</span> <span class="n">s.2</span> <span class="k">#check</span><span class="w"> </span><span class="n">s</span><span class="bp">.</span><span class="mi">1</span> <span class="k">#check</span><span class="w"> </span><span class="n">s</span><span class="bp">.</span><span class="mi">2</span> <span class="kd">end</span> </pre></div>
-
@@ -591,14 +592,14 @@ this is exactly what the <code class="docutils literal notranslate"><span class="pre">structure</span></code> command is designed to accommodate.It’s a marriage made in heaven!</p> <p>Given a data type <code class="docutils literal notranslate"><span class="pre">α</span></code>, we can define the group structure on <code class="docutils literal notranslate"><span class="pre">α</span></code> as follows.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">structure</span> <span class="n">Group₁</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">)</span> <span class="n">where</span> <span class="n">mul</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">α</span> <span class="n">one</span> <span class="o">:</span> <span class="n">α</span> <span class="n">inv</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">α</span> <span class="n">mul_assoc</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="n">y</span> <span class="n">z</span> <span class="o">:</span> <span class="n">α</span><span class="o">,</span> <span class="n">mul</span> <span class="o">(</span><span class="n">mul</span> <span class="n">x</span> <span class="n">y</span><span class="o">)</span> <span class="n">z</span> <span class="bp">=</span> <span class="n">mul</span> <span class="n">x</span> <span class="o">(</span><span class="n">mul</span> <span class="n">y</span> <span class="n">z</span><span class="o">)</span> <span class="n">mul_one</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="o">:</span> <span class="n">α</span><span class="o">,</span> <span class="n">mul</span> <span class="n">x</span> <span class="n">one</span> <span class="bp">=</span> <span class="n">x</span> <span class="n">one_mul</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="o">:</span> <span class="n">α</span><span class="o">,</span> <span class="n">mul</span> <span class="n">one</span> <span class="n">x</span> <span class="bp">=</span> <span class="n">x</span> <span class="n">inv_mul_cancel</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="o">:</span> <span class="n">α</span><span class="o">,</span> <span class="n">mul</span> <span class="o">(</span><span class="n">inv</span> <span class="n">x</span><span class="o">)</span> <span class="n">x</span> <span class="bp">=</span> <span class="n">one</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">structure</span><span class="w"> </span><span class="n">Group₁</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span> <span class="w"> </span><span class="n">one</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span> <span class="w"> </span><span class="n">inv</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span> <span class="w"> </span><span class="n">mul_assoc</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="o">(</span><span class="n">mul</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">(</span><span class="n">mul</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="o">)</span> <span class="w"> </span><span class="n">mul_one</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">one</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="n">one_mul</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="n">one</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="n">inv_mul_cancel</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="o">(</span><span class="n">inv</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">one</span> </pre></div> </div> <p>Notice that the type <code class="docutils literal notranslate"><span class="pre">α</span></code> is a <em>parameter</em> in the definition of <code class="docutils literal notranslate"><span class="pre">Group₁</span></code>.
-
@@ -627,9 +628,9 @@ <p>It is sometimes useful to bundlethe type together with the structure, and Mathlib also contains a definition of a <code class="docutils literal notranslate"><span class="pre">GroupCat</span></code> structure that is equivalent to the following:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">structure</span> <span class="n">Group₁Cat</span> <span class="n">where</span> <span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span> <span class="n">str</span> <span class="o">:</span> <span class="n">Group₁</span> <span class="n">α</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">structure</span><span class="w"> </span><span class="n">Group₁Cat</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span> <span class="w"> </span><span class="n">str</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Group₁</span><span class="w"> </span><span class="n">α</span> </pre></div> </div> <p>The Mathlib version is found in <code class="docutils literal notranslate"><span class="pre">Mathlib.Algebra.Category.GroupCat.Basic</span></code>,
-
@@ -652,17 +653,17 @@ a function <code class="docutils literal notranslate"><span class="pre">f.toFun</span></code> from <code class="docutils literal notranslate"><span class="pre">α</span></code> to <code class="docutils literal notranslate"><span class="pre">β</span></code>,the inverse function <code class="docutils literal notranslate"><span class="pre">f.invFun</span></code> from <code class="docutils literal notranslate"><span class="pre">β</span></code> to <code class="docutils literal notranslate"><span class="pre">α</span></code>, and two properties that specify these functions are indeed inverse to one another.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">(</span><span class="n">α</span> <span class="n">β</span> <span class="n">γ</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">)</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">≃</span> <span class="n">β</span><span class="o">)</span> <span class="o">(</span><span class="n">g</span> <span class="o">:</span> <span class="n">β</span> <span class="bp">≃</span> <span class="n">γ</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="n">γ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">≃</span><span class="w"> </span><span class="n">β</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="bp">≃</span><span class="w"> </span><span class="n">γ</span><span class="o">)</span> <span class="k">#check</span> <span class="n">Equiv</span> <span class="n">α</span> <span class="n">β</span> <span class="k">#check</span> <span class="o">(</span><span class="n">f.toFun</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">β</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">f.invFun</span> <span class="o">:</span> <span class="n">β</span> <span class="bp">→</span> <span class="n">α</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">f.right_inv</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="o">:</span> <span class="n">β</span><span class="o">,</span> <span class="n">f</span> <span class="o">(</span><span class="n">f.invFun</span> <span class="n">x</span><span class="o">)</span> <span class="bp">=</span> <span class="n">x</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">f.left_inv</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="o">:</span> <span class="n">α</span><span class="o">,</span> <span class="n">f.invFun</span> <span class="o">(</span><span class="n">f</span> <span class="n">x</span><span class="o">)</span> <span class="bp">=</span> <span class="n">x</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">Equiv.refl</span> <span class="n">α</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">≃</span> <span class="n">α</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">f.symm</span> <span class="o">:</span> <span class="n">β</span> <span class="bp">≃</span> <span class="n">α</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">f.trans</span> <span class="n">g</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">≃</span> <span class="n">γ</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="n">Equiv</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="n">β</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">f.toFun</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">β</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">f.invFun</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">f.right_inv</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">β</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">f.invFun</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">f.left_inv</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">f.invFun</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">Equiv.refl</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">≃</span><span class="w"> </span><span class="n">α</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">f.symm</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="bp">≃</span><span class="w"> </span><span class="n">α</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">f.trans</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">≃</span><span class="w"> </span><span class="n">γ</span><span class="o">)</span> </pre></div> </div> <p>Notice the creative naming of the last three constructions. We think of the
-
@@ -673,20 +674,20 @@ <p>Notice also that <code class="docutils literal notranslate"><span class="pre">f.trans</span> <span class="pre">g</span></code> requires composing the forward functionsin reverse order. Mathlib has declared a <em>coercion</em> from <code class="docutils literal notranslate"><span class="pre">Equiv</span> <span class="pre">α</span> <span class="pre">β</span></code> to the function type <code class="docutils literal notranslate"><span class="pre">α</span> <span class="pre">→</span> <span class="pre">β</span></code>, so we can omit writing <code class="docutils literal notranslate"><span class="pre">.toFun</span></code> and have Lean insert it for us.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">α</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">f.trans</span> <span class="n">g</span><span class="o">)</span><span class="bp">.</span><span class="n">toFun</span> <span class="n">x</span> <span class="bp">=</span> <span class="n">g.toFun</span> <span class="o">(</span><span class="n">f.toFun</span> <span class="n">x</span><span class="o">)</span> <span class="o">:=</span> <span class="n">rfl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">f.trans</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="bp">.</span><span class="n">toFun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">g.toFun</span><span class="w"> </span><span class="o">(</span><span class="n">f.toFun</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">α</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">f.trans</span> <span class="n">g</span><span class="o">)</span> <span class="n">x</span> <span class="bp">=</span> <span class="n">g</span> <span class="o">(</span><span class="n">f</span> <span class="n">x</span><span class="o">)</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">f.trans</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">f.trans</span> <span class="n">g</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">γ</span><span class="o">)</span> <span class="bp">=</span> <span class="n">g</span> <span class="bp">∘</span> <span class="n">f</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">f.trans</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">γ</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">∘</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> </pre></div> </div> <p>Mathlib also defines the type <code class="docutils literal notranslate"><span class="pre">perm</span> <span class="pre">α</span></code> of equivalences between <code class="docutils literal notranslate"><span class="pre">α</span></code> and itself.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">)</span> <span class="o">:</span> <span class="n">Equiv.Perm</span> <span class="n">α</span> <span class="bp">=</span> <span class="o">(</span><span class="n">α</span> <span class="bp">≃</span> <span class="n">α</span><span class="o">)</span> <span class="o">:=</span> <span class="n">rfl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Equiv.Perm</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="bp">≃</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> </pre></div> </div> <p>It should be clear that <code class="docutils literal notranslate"><span class="pre">Equiv.Perm</span> <span class="pre">α</span></code> forms a group under composition
-
@@ -694,15 +695,15 @@ of equivalences. We orient things so that <code class="docutils literal notranslate"><span class="pre">mul</span> <span class="pre">f</span> <span class="pre">g</span></code> isequal to <code class="docutils literal notranslate"><span class="pre">g.trans</span> <span class="pre">f</span></code>, whose forward function is <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">∘</span> <span class="pre">g</span></code>. In other words, multiplication is what we ordinarily think of as composition of the bijections. Here we define this group:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">permGroup</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">:</span> <span class="n">Group₁</span> <span class="o">(</span><span class="n">Equiv.Perm</span> <span class="n">α</span><span class="o">)</span> <span class="n">where</span> <span class="n">mul</span> <span class="n">f</span> <span class="n">g</span> <span class="o">:=</span> <span class="n">Equiv.trans</span> <span class="n">g</span> <span class="n">f</span> <span class="n">one</span> <span class="o">:=</span> <span class="n">Equiv.refl</span> <span class="n">α</span> <span class="n">inv</span> <span class="o">:=</span> <span class="n">Equiv.symm</span> <span class="n">mul_assoc</span> <span class="n">f</span> <span class="n">g</span> <span class="n">h</span> <span class="o">:=</span> <span class="o">(</span><span class="n">Equiv.trans_assoc</span> <span class="n">_</span> <span class="n">_</span> <span class="n">_</span><span class="o">)</span><span class="bp">.</span><span class="n">symm</span> <span class="n">one_mul</span> <span class="o">:=</span> <span class="n">Equiv.trans_refl</span> <span class="n">mul_one</span> <span class="o">:=</span> <span class="n">Equiv.refl_trans</span> <span class="n">inv_mul_cancel</span> <span class="o">:=</span> <span class="n">Equiv.self_trans_symm</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">permGroup</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Group₁</span><span class="w"> </span><span class="o">(</span><span class="n">Equiv.Perm</span><span class="w"> </span><span class="n">α</span><span class="o">)</span> <span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Equiv.trans</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">f</span> <span class="w"> </span><span class="n">one</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Equiv.refl</span><span class="w"> </span><span class="n">α</span> <span class="w"> </span><span class="n">inv</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Equiv.symm</span> <span class="w"> </span><span class="n">mul_assoc</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="n">Equiv.trans_assoc</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">_</span><span class="o">)</span><span class="bp">.</span><span class="n">symm</span> <span class="w"> </span><span class="n">one_mul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Equiv.trans_refl</span> <span class="w"> </span><span class="n">mul_one</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Equiv.refl_trans</span> <span class="w"> </span><span class="n">inv_mul_cancel</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Equiv.self_trans_symm</span> </pre></div> </div> <p>In fact, Mathlib defines exactly this <code class="docutils literal notranslate"><span class="pre">Group</span></code> structure on <code class="docutils literal notranslate"><span class="pre">Equiv.Perm</span> <span class="pre">α</span></code>
-
@@ -736,27 +737,27 @@ to the <code class="docutils literal notranslate"><span class="pre">Group₁</span></code> structure we defined above, except that it uses theadditive naming scheme just described. Define negation and a zero on the <code class="docutils literal notranslate"><span class="pre">Point</span></code> data type, and define the <code class="docutils literal notranslate"><span class="pre">AddGroup₁</span></code> structure on <code class="docutils literal notranslate"><span class="pre">Point</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">structure</span> <span class="n">AddGroup₁</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">)</span> <span class="n">where</span> <span class="o">(</span><span class="n">add</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">α</span><span class="o">)</span> <span class="c1">-- fill in the rest</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">structure</span><span class="w"> </span><span class="n">AddGroup₁</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="o">(</span><span class="n">add</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span><span class="o">)</span> <span class="w"> </span><span class="c1">-- fill in the rest</span> <span class="kd">@[</span><span class="n">ext</span><span class="kd">]</span> <span class="kd">structure</span> <span class="n">Point</span> <span class="n">where</span> <span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="n">z</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="kd">structure</span><span class="w"> </span><span class="n">Point</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span> <span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span> <span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span> <span class="kn">namespace</span> <span class="n">Point</span> <span class="kn">namespace</span><span class="w"> </span><span class="n">Point</span> <span class="kd">def</span> <span class="n">add</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">Point</span><span class="o">)</span> <span class="o">:</span> <span class="n">Point</span> <span class="o">:=</span> <span class="o">⟨</span><span class="n">a.x</span> <span class="bp">+</span> <span class="n">b.x</span><span class="o">,</span> <span class="n">a.y</span> <span class="bp">+</span> <span class="n">b.y</span><span class="o">,</span> <span class="n">a.z</span> <span class="bp">+</span> <span class="n">b.z</span><span class="o">⟩</span> <span class="kd">def</span><span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">⟨</span><span class="n">a.x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b.x</span><span class="o">,</span><span class="w"> </span><span class="n">a.y</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b.y</span><span class="o">,</span><span class="w"> </span><span class="n">a.z</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b.z</span><span class="o">⟩</span> <span class="kd">def</span> <span class="n">neg</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">Point</span><span class="o">)</span> <span class="o">:</span> <span class="n">Point</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">def</span><span class="w"> </span><span class="n">neg</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="kd">def</span> <span class="n">zero</span> <span class="o">:</span> <span class="n">Point</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">def</span><span class="w"> </span><span class="n">zero</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="kd">def</span> <span class="n">addGroupPoint</span> <span class="o">:</span> <span class="n">AddGroup₁</span> <span class="n">Point</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">def</span><span class="w"> </span><span class="n">addGroupPoint</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">AddGroup₁</span><span class="w"> </span><span class="n">Point</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="kd">end</span> <span class="n">Point</span> <span class="kd">end</span><span class="w"> </span><span class="n">Point</span> </pre></div> </div> <p>We are making progress.
-
@@ -770,21 +771,21 @@ and we want to arrange it so that we can prove a theorem abouta structure and use it with any instance.</p> <p>In fact, Mathlib is already set up to use generic group notation, definitions, and theorems for <code class="docutils literal notranslate"><span class="pre">Equiv.Perm</span> <span class="pre">α</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">(</span><span class="n">f</span> <span class="n">g</span> <span class="o">:</span> <span class="n">Equiv.Perm</span> <span class="n">α</span><span class="o">)</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Equiv.Perm</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span> <span class="k">#check</span> <span class="n">f</span> <span class="bp">*</span> <span class="n">g</span> <span class="k">#check</span> <span class="n">mul_assoc</span> <span class="n">f</span> <span class="n">g</span> <span class="n">g</span><span class="bp">⁻¹</span> <span class="k">#check</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g</span> <span class="k">#check</span><span class="w"> </span><span class="n">mul_assoc</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">g</span><span class="bp">⁻¹</span> <span class="c1">-- group power, defined for any group</span> <span class="k">#check</span> <span class="n">g</span> <span class="bp">^</span> <span class="n">n</span> <span class="k">#check</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="n">n</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">*</span> <span class="n">g</span> <span class="bp">*</span> <span class="n">g</span><span class="bp">⁻¹</span> <span class="bp">=</span> <span class="n">f</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mul_assoc</span><span class="o">,</span> <span class="n">mul_inv_cancel</span><span class="o">,</span> <span class="n">mul_one</span><span class="o">]</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g</span><span class="bp">⁻¹</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mul_assoc</span><span class="o">,</span><span class="w"> </span><span class="n">mul_inv_cancel</span><span class="o">,</span><span class="w"> </span><span class="n">mul_one</span><span class="o">]</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">*</span> <span class="n">g</span> <span class="bp">*</span> <span class="n">g</span><span class="bp">⁻¹</span> <span class="bp">=</span> <span class="n">f</span> <span class="o">:=</span> <span class="n">mul_inv_cancel_right</span> <span class="n">f</span> <span class="n">g</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g</span><span class="bp">⁻¹</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">mul_inv_cancel_right</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span> <span class="kd">example</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">(</span><span class="n">f</span> <span class="n">g</span> <span class="o">:</span> <span class="n">Equiv.Perm</span> <span class="n">α</span><span class="o">)</span> <span class="o">:</span> <span class="n">g.symm.trans</span> <span class="o">(</span><span class="n">g.trans</span> <span class="n">f</span><span class="o">)</span> <span class="bp">=</span> <span class="n">f</span> <span class="o">:=</span> <span class="n">mul_inv_cancel_right</span> <span class="n">f</span> <span class="n">g</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Equiv.Perm</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">g.symm.trans</span><span class="w"> </span><span class="o">(</span><span class="n">g.trans</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">mul_inv_cancel_right</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span> </pre></div> </div> <p>You can check that this is not the case for the additive group structure
-
@@ -848,41 +849,41 @@ Lean. As with the names of class variables, we are allowed to leave thename of an instance definition anonymous, since in general we intend Lean to find it and put it to use without troubling us with the details.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span> <span class="n">Group₂</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">)</span> <span class="n">where</span> <span class="n">mul</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">α</span> <span class="n">one</span> <span class="o">:</span> <span class="n">α</span> <span class="n">inv</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">α</span> <span class="n">mul_assoc</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="n">y</span> <span class="n">z</span> <span class="o">:</span> <span class="n">α</span><span class="o">,</span> <span class="n">mul</span> <span class="o">(</span><span class="n">mul</span> <span class="n">x</span> <span class="n">y</span><span class="o">)</span> <span class="n">z</span> <span class="bp">=</span> <span class="n">mul</span> <span class="n">x</span> <span class="o">(</span><span class="n">mul</span> <span class="n">y</span> <span class="n">z</span><span class="o">)</span> <span class="n">mul_one</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="o">:</span> <span class="n">α</span><span class="o">,</span> <span class="n">mul</span> <span class="n">x</span> <span class="n">one</span> <span class="bp">=</span> <span class="n">x</span> <span class="n">one_mul</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="o">:</span> <span class="n">α</span><span class="o">,</span> <span class="n">mul</span> <span class="n">one</span> <span class="n">x</span> <span class="bp">=</span> <span class="n">x</span> <span class="n">inv_mul_cancel</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="o">:</span> <span class="n">α</span><span class="o">,</span> <span class="n">mul</span> <span class="o">(</span><span class="n">inv</span> <span class="n">x</span><span class="o">)</span> <span class="n">x</span> <span class="bp">=</span> <span class="n">one</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span><span class="w"> </span><span class="n">Group₂</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span> <span class="w"> </span><span class="n">one</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span> <span class="w"> </span><span class="n">inv</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span> <span class="w"> </span><span class="n">mul_assoc</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="o">(</span><span class="n">mul</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">(</span><span class="n">mul</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="o">)</span> <span class="w"> </span><span class="n">mul_one</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">one</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="n">one_mul</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="n">one</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="n">inv_mul_cancel</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="o">(</span><span class="n">inv</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">one</span> <span class="kd">instance</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">:</span> <span class="n">Group₂</span> <span class="o">(</span><span class="n">Equiv.Perm</span> <span class="n">α</span><span class="o">)</span> <span class="n">where</span> <span class="n">mul</span> <span class="n">f</span> <span class="n">g</span> <span class="o">:=</span> <span class="n">Equiv.trans</span> <span class="n">g</span> <span class="n">f</span> <span class="n">one</span> <span class="o">:=</span> <span class="n">Equiv.refl</span> <span class="n">α</span> <span class="n">inv</span> <span class="o">:=</span> <span class="n">Equiv.symm</span> <span class="n">mul_assoc</span> <span class="n">f</span> <span class="n">g</span> <span class="n">h</span> <span class="o">:=</span> <span class="o">(</span><span class="n">Equiv.trans_assoc</span> <span class="n">_</span> <span class="n">_</span> <span class="n">_</span><span class="o">)</span><span class="bp">.</span><span class="n">symm</span> <span class="n">one_mul</span> <span class="o">:=</span> <span class="n">Equiv.trans_refl</span> <span class="n">mul_one</span> <span class="o">:=</span> <span class="n">Equiv.refl_trans</span> <span class="n">inv_mul_cancel</span> <span class="o">:=</span> <span class="n">Equiv.self_trans_symm</span> <span class="kd">instance</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Group₂</span><span class="w"> </span><span class="o">(</span><span class="n">Equiv.Perm</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Equiv.trans</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">f</span> <span class="w"> </span><span class="n">one</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Equiv.refl</span><span class="w"> </span><span class="n">α</span> <span class="w"> </span><span class="n">inv</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Equiv.symm</span> <span class="w"> </span><span class="n">mul_assoc</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="n">Equiv.trans_assoc</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">_</span><span class="o">)</span><span class="bp">.</span><span class="n">symm</span> <span class="w"> </span><span class="n">one_mul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Equiv.trans_refl</span> <span class="w"> </span><span class="n">mul_one</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Equiv.refl_trans</span> <span class="w"> </span><span class="n">inv_mul_cancel</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Equiv.self_trans_symm</span> </pre></div> </div> <p>The following illustrates their use.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="n">Group₂.mul</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="n">Group₂.mul</span> <span class="kd">def</span> <span class="n">mySquare</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group₂</span> <span class="n">α</span><span class="o">]</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">α</span><span class="o">)</span> <span class="o">:=</span> <span class="n">Group₂.mul</span> <span class="n">x</span> <span class="n">x</span> <span class="kd">def</span><span class="w"> </span><span class="n">mySquare</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group₂</span><span class="w"> </span><span class="n">α</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Group₂.mul</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">x</span> <span class="k">#check</span> <span class="n">mySquare</span> <span class="k">#check</span><span class="w"> </span><span class="n">mySquare</span> <span class="kn">section</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">β</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">(</span><span class="n">f</span> <span class="n">g</span> <span class="o">:</span> <span class="n">Equiv.Perm</span> <span class="n">β</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">β</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Equiv.Perm</span><span class="w"> </span><span class="n">β</span><span class="o">)</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">Group₂.mul</span> <span class="n">f</span> <span class="n">g</span> <span class="bp">=</span> <span class="n">g.trans</span> <span class="n">f</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Group₂.mul</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">g.trans</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">mySquare</span> <span class="n">f</span> <span class="bp">=</span> <span class="n">f.trans</span> <span class="n">f</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">mySquare</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f.trans</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">end</span> </pre></div>
-
@@ -915,12 +916,12 @@ element of a list, can return the default value when the list is empty.To make that work, the Lean library defines a class <code class="docutils literal notranslate"><span class="pre">Inhabited</span> <span class="pre">α</span></code>, which does nothing more than store a default value. We can show that the <code class="docutils literal notranslate"><span class="pre">Point</span></code> type is an instance:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span> <span class="o">:</span> <span class="n">Inhabited</span> <span class="n">Point</span> <span class="n">where</span> <span class="n">default</span> <span class="o">:=</span> <span class="o">⟨</span><span class="mi">0</span><span class="o">,</span> <span class="mi">0</span><span class="o">,</span> <span class="mi">0</span><span class="o">⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Inhabited</span><span class="w"> </span><span class="n">Point</span><span class="w"> </span><span class="n">where</span><span class="w"> </span><span class="n">default</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">⟨</span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="mi">0</span><span class="o">⟩</span> <span class="k">#check</span> <span class="o">(</span><span class="n">default</span> <span class="o">:</span> <span class="n">Point</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">default</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="o">)</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">([]</span> <span class="o">:</span> <span class="n">List</span> <span class="n">Point</span><span class="o">)</span><span class="bp">.</span><span class="n">headI</span> <span class="bp">=</span> <span class="n">default</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">([]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">List</span><span class="w"> </span><span class="n">Point</span><span class="o">)</span><span class="bp">.</span><span class="n">headI</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">default</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> </pre></div> </div> <p>The class inference mechanism is also used for generic notation.
-
@@ -930,15 +931,15 @@ a binary function on <code class="docutils literal notranslate"><span class="pre">α</span></code>.Writing <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">+</span> <span class="pre">y</span></code> tells Lean to find a registered instance of <code class="docutils literal notranslate"><span class="pre">[Add.add</span> <span class="pre">α]</span></code> and use the corresponding function. Below, we register the addition function for <code class="docutils literal notranslate"><span class="pre">Point</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span> <span class="o">:</span> <span class="n">Add</span> <span class="n">Point</span> <span class="n">where</span> <span class="n">add</span> <span class="o">:=</span> <span class="n">Point.add</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Add</span><span class="w"> </span><span class="n">Point</span><span class="w"> </span><span class="n">where</span><span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Point.add</span> <span class="kn">section</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">Point</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Point</span><span class="o">)</span> <span class="k">#check</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">y</span> <span class="k">#check</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">y</span> <span class="bp">=</span> <span class="n">Point.add</span> <span class="n">x</span> <span class="n">y</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">Point.add</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">end</span> </pre></div>
-
@@ -952,22 +953,22 @@ When we define a new instance of a ring in Lean,we don’t have to define <code class="docutils literal notranslate"><span class="pre">+</span></code> and <code class="docutils literal notranslate"><span class="pre">*</span></code> for that instance, because Lean knows that these are defined for every ring. We can use this method to specify notation for our <code class="docutils literal notranslate"><span class="pre">Group₂</span></code> class:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span> <span class="n">hasMulGroup₂</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group₂</span> <span class="n">α</span><span class="o">]</span> <span class="o">:</span> <span class="n">Mul</span> <span class="n">α</span> <span class="o">:=</span> <span class="o">⟨</span><span class="n">Group₂.mul</span><span class="o">⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span><span class="w"> </span><span class="n">hasMulGroup₂</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group₂</span><span class="w"> </span><span class="n">α</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Mul</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">⟨</span><span class="n">Group₂.mul</span><span class="o">⟩</span> <span class="kd">instance</span> <span class="n">hasOneGroup₂</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group₂</span> <span class="n">α</span><span class="o">]</span> <span class="o">:</span> <span class="n">One</span> <span class="n">α</span> <span class="o">:=</span> <span class="o">⟨</span><span class="n">Group₂.one</span><span class="o">⟩</span> <span class="kd">instance</span><span class="w"> </span><span class="n">hasOneGroup₂</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group₂</span><span class="w"> </span><span class="n">α</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">One</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">⟨</span><span class="n">Group₂.one</span><span class="o">⟩</span> <span class="kd">instance</span> <span class="n">hasInvGroup₂</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group₂</span> <span class="n">α</span><span class="o">]</span> <span class="o">:</span> <span class="n">Inv</span> <span class="n">α</span> <span class="o">:=</span> <span class="o">⟨</span><span class="n">Group₂.inv</span><span class="o">⟩</span> <span class="kd">instance</span><span class="w"> </span><span class="n">hasInvGroup₂</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group₂</span><span class="w"> </span><span class="n">α</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Inv</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">⟨</span><span class="n">Group₂.inv</span><span class="o">⟩</span> <span class="kn">section</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">(</span><span class="n">f</span> <span class="n">g</span> <span class="o">:</span> <span class="n">Equiv.Perm</span> <span class="n">α</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Equiv.Perm</span><span class="w"> </span><span class="n">α</span><span class="o">)</span> <span class="k">#check</span> <span class="n">f</span> <span class="bp">*</span> <span class="mi">1</span> <span class="bp">*</span> <span class="n">g</span><span class="bp">⁻¹</span> <span class="k">#check</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g</span><span class="bp">⁻¹</span> <span class="kd">def</span> <span class="n">foo</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">*</span> <span class="mi">1</span> <span class="bp">*</span> <span class="n">g</span><span class="bp">⁻¹</span> <span class="bp">=</span> <span class="n">g.symm.trans</span> <span class="o">((</span><span class="n">Equiv.refl</span> <span class="n">α</span><span class="o">)</span><span class="bp">.</span><span class="n">trans</span> <span class="n">f</span><span class="o">)</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">def</span><span class="w"> </span><span class="n">foo</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g</span><span class="bp">⁻¹</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">g.symm.trans</span><span class="w"> </span><span class="o">((</span><span class="n">Equiv.refl</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="bp">.</span><span class="n">trans</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">end</span> </pre></div>
-
@@ -1006,9 +1007,9 @@ using the classes <code class="docutils literal notranslate"><span class="pre">Add</span></code>, <code class="docutils literal notranslate"><span class="pre">Neg</span></code>, and <code class="docutils literal notranslate"><span class="pre">Zero</span></code>.Then show <code class="docutils literal notranslate"><span class="pre">Point</span></code> is an instance of <code class="docutils literal notranslate"><span class="pre">AddGroup₂</span></code>. Try it out and make sure that the additive group notation works for elements of <code class="docutils literal notranslate"><span class="pre">Point</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span> <span class="n">AddGroup₂</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">)</span> <span class="n">where</span> <span class="n">add</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">α</span> <span class="c1">-- fill in the rest</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span><span class="w"> </span><span class="n">AddGroup₂</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span> <span class="w"> </span><span class="c1">-- fill in the rest</span> </pre></div> </div> <p>It is not a big problem that we have already declared instances
-
@@ -1035,9 +1036,9 @@ here is to define them as a data type in their own right. We do this byrepresenting a Gaussian integer as a pair of integers, which we think of as the <em>real</em> and <em>imaginary</em> parts.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">@[</span><span class="n">ext</span><span class="kd">]</span> <span class="kd">structure</span> <span class="n">GaussInt</span> <span class="n">where</span> <span class="n">re</span> <span class="o">:</span> <span class="n">ℤ</span> <span class="n">im</span> <span class="o">:</span> <span class="n">ℤ</span> <span class="kd">structure</span><span class="w"> </span><span class="n">GaussInt</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">re</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℤ</span> <span class="w"> </span><span class="n">im</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℤ</span> </pre></div> </div> <p>We first show that the Gaussian integers have the structure of a ring,
-
@@ -1049,20 +1050,20 @@ <div class="math notranslate nohighlight">\[\begin{split}(a + bi) (c + di) & = ac + bci + adi + bd i^2 \\ & = (ac - bd) + (bc + ad)i.\end{split}\]</div> <p>This explains the definition of <code class="docutils literal notranslate"><span class="pre">Mul</span></code> below.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span> <span class="o">:</span> <span class="n">Zero</span> <span class="n">GaussInt</span> <span class="o">:=</span> <span class="o">⟨⟨</span><span class="mi">0</span><span class="o">,</span> <span class="mi">0</span><span class="o">⟩⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Zero</span><span class="w"> </span><span class="n">GaussInt</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">⟨⟨</span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="mi">0</span><span class="o">⟩⟩</span> <span class="kd">instance</span> <span class="o">:</span> <span class="n">One</span> <span class="n">GaussInt</span> <span class="o">:=</span> <span class="o">⟨⟨</span><span class="mi">1</span><span class="o">,</span> <span class="mi">0</span><span class="o">⟩⟩</span> <span class="kd">instance</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">One</span><span class="w"> </span><span class="n">GaussInt</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">⟨⟨</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">0</span><span class="o">⟩⟩</span> <span class="kd">instance</span> <span class="o">:</span> <span class="n">Add</span> <span class="n">GaussInt</span> <span class="o">:=</span> <span class="o">⟨</span><span class="k">fun</span> <span class="n">x</span> <span class="n">y</span> <span class="bp">↦</span> <span class="o">⟨</span><span class="n">x.re</span> <span class="bp">+</span> <span class="n">y.re</span><span class="o">,</span> <span class="n">x.im</span> <span class="bp">+</span> <span class="n">y.im</span><span class="o">⟩⟩</span> <span class="kd">instance</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Add</span><span class="w"> </span><span class="n">GaussInt</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">⟨</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">⟨</span><span class="n">x.re</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y.re</span><span class="o">,</span><span class="w"> </span><span class="n">x.im</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y.im</span><span class="o">⟩⟩</span> <span class="kd">instance</span> <span class="o">:</span> <span class="n">Neg</span> <span class="n">GaussInt</span> <span class="o">:=</span> <span class="o">⟨</span><span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="o">⟨</span><span class="bp">-</span><span class="n">x.re</span><span class="o">,</span> <span class="bp">-</span><span class="n">x.im</span><span class="o">⟩⟩</span> <span class="kd">instance</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Neg</span><span class="w"> </span><span class="n">GaussInt</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">⟨</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">⟨</span><span class="bp">-</span><span class="n">x.re</span><span class="o">,</span><span class="w"> </span><span class="bp">-</span><span class="n">x.im</span><span class="o">⟩⟩</span> <span class="kd">instance</span> <span class="o">:</span> <span class="n">Mul</span> <span class="n">GaussInt</span> <span class="o">:=</span> <span class="o">⟨</span><span class="k">fun</span> <span class="n">x</span> <span class="n">y</span> <span class="bp">↦</span> <span class="o">⟨</span><span class="n">x.re</span> <span class="bp">*</span> <span class="n">y.re</span> <span class="bp">-</span> <span class="n">x.im</span> <span class="bp">*</span> <span class="n">y.im</span><span class="o">,</span> <span class="n">x.re</span> <span class="bp">*</span> <span class="n">y.im</span> <span class="bp">+</span> <span class="n">x.im</span> <span class="bp">*</span> <span class="n">y.re</span><span class="o">⟩⟩</span> <span class="kd">instance</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Mul</span><span class="w"> </span><span class="n">GaussInt</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">⟨</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">⟨</span><span class="n">x.re</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y.re</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">x.im</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y.im</span><span class="o">,</span><span class="w"> </span><span class="n">x.re</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y.im</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">x.im</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y.re</span><span class="o">⟩⟩</span> </pre></div> </div> <p>As noted in <a class="reference internal" href="#section-structures"><span class="std std-numref">Section 6.1</span></a>, it is a good idea to put all the definitions
-
@@ -1074,64 +1075,64 @@ <code class="docutils literal notranslate"><span class="pre">1</span></code>, <code class="docutils literal notranslate"><span class="pre">+</span></code>, <code class="docutils literal notranslate"><span class="pre">-</span></code>, and <code class="docutils literal notranslate"><span class="pre">*</span></code> directly, rather than naming them<code class="docutils literal notranslate"><span class="pre">GaussInt.zero</span></code> and the like and assigning the notation to those. It is often useful to have an explicit name for the definitions, for example, to use with <code class="docutils literal notranslate"><span class="pre">simp</span></code> and <code class="docutils literal notranslate"><span class="pre">rewrite</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">zero_def</span> <span class="o">:</span> <span class="o">(</span><span class="mi">0</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="bp">=</span> <span class="o">⟨</span><span class="mi">0</span><span class="o">,</span> <span class="mi">0</span><span class="o">⟩</span> <span class="o">:=</span> <span class="n">rfl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">zero_def</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="mi">0</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">⟨</span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="mi">0</span><span class="o">⟩</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">theorem</span> <span class="n">one_def</span> <span class="o">:</span> <span class="o">(</span><span class="mi">1</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="bp">=</span> <span class="o">⟨</span><span class="mi">1</span><span class="o">,</span> <span class="mi">0</span><span class="o">⟩</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">one_def</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">⟨</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">0</span><span class="o">⟩</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">theorem</span> <span class="n">add_def</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">y</span> <span class="bp">=</span> <span class="o">⟨</span><span class="n">x.re</span> <span class="bp">+</span> <span class="n">y.re</span><span class="o">,</span> <span class="n">x.im</span> <span class="bp">+</span> <span class="n">y.im</span><span class="o">⟩</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">add_def</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">⟨</span><span class="n">x.re</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y.re</span><span class="o">,</span><span class="w"> </span><span class="n">x.im</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y.im</span><span class="o">⟩</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">theorem</span> <span class="n">neg_def</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">:</span> <span class="bp">-</span><span class="n">x</span> <span class="bp">=</span> <span class="o">⟨</span><span class="bp">-</span><span class="n">x.re</span><span class="o">,</span> <span class="bp">-</span><span class="n">x.im</span><span class="o">⟩</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">neg_def</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">-</span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">⟨</span><span class="bp">-</span><span class="n">x.re</span><span class="o">,</span><span class="w"> </span><span class="bp">-</span><span class="n">x.im</span><span class="o">⟩</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">theorem</span> <span class="n">mul_def</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">*</span> <span class="n">y</span> <span class="bp">=</span> <span class="o">⟨</span><span class="n">x.re</span> <span class="bp">*</span> <span class="n">y.re</span> <span class="bp">-</span> <span class="n">x.im</span> <span class="bp">*</span> <span class="n">y.im</span><span class="o">,</span> <span class="n">x.re</span> <span class="bp">*</span> <span class="n">y.im</span> <span class="bp">+</span> <span class="n">x.im</span> <span class="bp">*</span> <span class="n">y.re</span><span class="o">⟩</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">mul_def</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">⟨</span><span class="n">x.re</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y.re</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">x.im</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y.im</span><span class="o">,</span><span class="w"> </span><span class="n">x.re</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y.im</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">x.im</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y.re</span><span class="o">⟩</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> </pre></div> </div> <p>It is also useful to name the rules that compute the real and imaginary parts, and to declare them to the simplifier.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">@[</span><span class="n">simp</span><span class="kd">]</span> <span class="kd">theorem</span> <span class="n">zero_re</span> <span class="o">:</span> <span class="o">(</span><span class="mi">0</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span><span class="bp">.</span><span class="n">re</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">zero_re</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="mi">0</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="bp">.</span><span class="n">re</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">@[</span><span class="n">simp</span><span class="kd">]</span> <span class="kd">theorem</span> <span class="n">zero_im</span> <span class="o">:</span> <span class="o">(</span><span class="mi">0</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span><span class="bp">.</span><span class="n">im</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">zero_im</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="mi">0</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="bp">.</span><span class="n">im</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">@[</span><span class="n">simp</span><span class="kd">]</span> <span class="kd">theorem</span> <span class="n">one_re</span> <span class="o">:</span> <span class="o">(</span><span class="mi">1</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span><span class="bp">.</span><span class="n">re</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">one_re</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="bp">.</span><span class="n">re</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">@[</span><span class="n">simp</span><span class="kd">]</span> <span class="kd">theorem</span> <span class="n">one_im</span> <span class="o">:</span> <span class="o">(</span><span class="mi">1</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span><span class="bp">.</span><span class="n">im</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">one_im</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="bp">.</span><span class="n">im</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">@[</span><span class="n">simp</span><span class="kd">]</span> <span class="kd">theorem</span> <span class="n">add_re</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">x</span> <span class="bp">+</span> <span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">re</span> <span class="bp">=</span> <span class="n">x.re</span> <span class="bp">+</span> <span class="n">y.re</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">add_re</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">re</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x.re</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y.re</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">@[</span><span class="n">simp</span><span class="kd">]</span> <span class="kd">theorem</span> <span class="n">add_im</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">x</span> <span class="bp">+</span> <span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">im</span> <span class="bp">=</span> <span class="n">x.im</span> <span class="bp">+</span> <span class="n">y.im</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">add_im</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">im</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x.im</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y.im</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">@[</span><span class="n">simp</span><span class="kd">]</span> <span class="kd">theorem</span> <span class="n">neg_re</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="bp">-</span><span class="n">x</span><span class="o">)</span><span class="bp">.</span><span class="n">re</span> <span class="bp">=</span> <span class="bp">-</span><span class="n">x.re</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">neg_re</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">-</span><span class="n">x</span><span class="o">)</span><span class="bp">.</span><span class="n">re</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">-</span><span class="n">x.re</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">@[</span><span class="n">simp</span><span class="kd">]</span> <span class="kd">theorem</span> <span class="n">neg_im</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="bp">-</span><span class="n">x</span><span class="o">)</span><span class="bp">.</span><span class="n">im</span> <span class="bp">=</span> <span class="bp">-</span><span class="n">x.im</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">neg_im</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">-</span><span class="n">x</span><span class="o">)</span><span class="bp">.</span><span class="n">im</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">-</span><span class="n">x.im</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">@[</span><span class="n">simp</span><span class="kd">]</span> <span class="kd">theorem</span> <span class="n">mul_re</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">x</span> <span class="bp">*</span> <span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">re</span> <span class="bp">=</span> <span class="n">x.re</span> <span class="bp">*</span> <span class="n">y.re</span> <span class="bp">-</span> <span class="n">x.im</span> <span class="bp">*</span> <span class="n">y.im</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">mul_re</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">re</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x.re</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y.re</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">x.im</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y.im</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">@[</span><span class="n">simp</span><span class="kd">]</span> <span class="kd">theorem</span> <span class="n">mul_im</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">x</span> <span class="bp">*</span> <span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">im</span> <span class="bp">=</span> <span class="n">x.re</span> <span class="bp">*</span> <span class="n">y.im</span> <span class="bp">+</span> <span class="n">x.im</span> <span class="bp">*</span> <span class="n">y.re</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">mul_im</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">im</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x.re</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y.im</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">x.im</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y.re</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> </pre></div> </div> <p>It is now surprisingly easy to show that the Gaussian integers are an instance
-
@@ -1155,63 +1156,63 @@ to reduce the identities to their real and imaginary components,simplifying, and, if necessary, carrying out the relevant ring calculation in the integers. Note that we could easily avoid repeating all this code, but this is not the topic of the current discussion.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span> <span class="n">instCommRing</span> <span class="o">:</span> <span class="n">CommRing</span> <span class="n">GaussInt</span> <span class="n">where</span> <span class="n">zero</span> <span class="o">:=</span> <span class="mi">0</span> <span class="n">one</span> <span class="o">:=</span> <span class="mi">1</span> <span class="n">add</span> <span class="o">:=</span> <span class="o">(</span><span class="bp">·</span> <span class="bp">+</span> <span class="bp">·</span><span class="o">)</span> <span class="n">neg</span> <span class="n">x</span> <span class="o">:=</span> <span class="bp">-</span><span class="n">x</span> <span class="n">mul</span> <span class="o">:=</span> <span class="o">(</span><span class="bp">·</span> <span class="bp">*</span> <span class="bp">·</span><span class="o">)</span> <span class="n">nsmul</span> <span class="o">:=</span> <span class="n">nsmulRec</span> <span class="n">zsmul</span> <span class="o">:=</span> <span class="n">zsmulRec</span> <span class="n">add_assoc</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intros</span> <span class="n">ext</span> <span class="bp"><;></span> <span class="n">simp</span> <span class="bp"><;></span> <span class="n">ring</span> <span class="n">zero_add</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">ext</span> <span class="bp"><;></span> <span class="n">simp</span> <span class="n">add_zero</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">ext</span> <span class="bp"><;></span> <span class="n">simp</span> <span class="n">neg_add_cancel</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">ext</span> <span class="bp"><;></span> <span class="n">simp</span> <span class="n">add_comm</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intros</span> <span class="n">ext</span> <span class="bp"><;></span> <span class="n">simp</span> <span class="bp"><;></span> <span class="n">ring</span> <span class="n">mul_assoc</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intros</span> <span class="n">ext</span> <span class="bp"><;></span> <span class="n">simp</span> <span class="bp"><;></span> <span class="n">ring</span> <span class="n">one_mul</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">ext</span> <span class="bp"><;></span> <span class="n">simp</span> <span class="n">mul_one</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">ext</span> <span class="bp"><;></span> <span class="n">simp</span> <span class="n">left_distrib</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intros</span> <span class="n">ext</span> <span class="bp"><;></span> <span class="n">simp</span> <span class="bp"><;></span> <span class="n">ring</span> <span class="n">right_distrib</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intros</span> <span class="n">ext</span> <span class="bp"><;></span> <span class="n">simp</span> <span class="bp"><;></span> <span class="n">ring</span> <span class="n">mul_comm</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intros</span> <span class="n">ext</span> <span class="bp"><;></span> <span class="n">simp</span> <span class="bp"><;></span> <span class="n">ring</span> <span class="n">zero_mul</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intros</span> <span class="n">ext</span> <span class="bp"><;></span> <span class="n">simp</span> <span class="n">mul_zero</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intros</span> <span class="n">ext</span> <span class="bp"><;></span> <span class="n">simp</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span><span class="w"> </span><span class="n">instCommRing</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">CommRing</span><span class="w"> </span><span class="n">GaussInt</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">zero</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">0</span> <span class="w"> </span><span class="n">one</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">1</span> <span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="bp">·</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="bp">·</span><span class="o">)</span> <span class="w"> </span><span class="n">neg</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="bp">-</span><span class="n">x</span> <span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="bp">·</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="bp">·</span><span class="o">)</span> <span class="w"> </span><span class="n">nsmul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">nsmulRec</span> <span class="w"> </span><span class="n">zsmul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">zsmulRec</span> <span class="w"> </span><span class="n">add_assoc</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intros</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">ring</span> <span class="w"> </span><span class="n">zero_add</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="n">add_zero</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="n">neg_add_cancel</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="n">add_comm</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intros</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">ring</span> <span class="w"> </span><span class="n">mul_assoc</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intros</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">ring</span> <span class="w"> </span><span class="n">one_mul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="n">mul_one</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="n">left_distrib</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intros</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">ring</span> <span class="w"> </span><span class="n">right_distrib</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intros</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">ring</span> <span class="w"> </span><span class="n">mul_comm</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intros</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">ring</span> <span class="w"> </span><span class="n">zero_mul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intros</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="n">mul_zero</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intros</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">simp</span> </pre></div> </div> <p>Lean’s library defines the class of <em>nontrivial</em> types to be types with at least two distinct elements. In the context of a ring, this is equivalent to saying that the zero is not equal to the one. Since some common theorems depend on that fact, we may as well establish it now.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span> <span class="o">:</span> <span class="n">Nontrivial</span> <span class="n">GaussInt</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">use</span> <span class="mi">0</span><span class="o">,</span> <span class="mi">1</span> <span class="n">rw</span> <span class="o">[</span><span class="n">Ne</span><span class="o">,</span> <span class="n">GaussInt.ext_iff</span><span class="o">]</span> <span class="n">simp</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nontrivial</span><span class="w"> </span><span class="n">GaussInt</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">Ne</span><span class="o">,</span><span class="w"> </span><span class="n">GaussInt.ext_iff</span><span class="o">]</span> <span class="w"> </span><span class="n">simp</span> </pre></div> </div> <p>We will now show that the Gaussian integers have an important additional
-
@@ -1229,14 +1230,14 @@ In that case, we can take <span class="math notranslate nohighlight">\(q\)</span> to be theresult of integer division of <span class="math notranslate nohighlight">\(a\)</span> by <span class="math notranslate nohighlight">\(b\)</span> and <span class="math notranslate nohighlight">\(r\)</span> to be the remainder. These functions are defined in Lean so that the satisfy the following:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℤ</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">=</span> <span class="n">b</span> <span class="bp">*</span> <span class="o">(</span><span class="n">a</span> <span class="bp">/</span> <span class="n">b</span><span class="o">)</span> <span class="bp">+</span> <span class="n">a</span> <span class="bp">%</span> <span class="n">b</span> <span class="o">:=</span> <span class="n">Eq.symm</span> <span class="o">(</span><span class="n">Int.ediv_add_emod</span> <span class="n">a</span> <span class="n">b</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℤ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Eq.symm</span><span class="w"> </span><span class="o">(</span><span class="n">Int.ediv_add_emod</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> <span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℤ</span><span class="o">)</span> <span class="o">:</span> <span class="n">b</span> <span class="bp">≠</span> <span class="mi">0</span> <span class="bp">→</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">a</span> <span class="bp">%</span> <span class="n">b</span> <span class="o">:=</span> <span class="n">Int.emod_nonneg</span> <span class="n">a</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℤ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Int.emod_nonneg</span><span class="w"> </span><span class="n">a</span> <span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℤ</span><span class="o">)</span> <span class="o">:</span> <span class="n">b</span> <span class="bp">≠</span> <span class="mi">0</span> <span class="bp">→</span> <span class="n">a</span> <span class="bp">%</span> <span class="n">b</span> <span class="bp"><</span> <span class="bp">|</span><span class="n">b</span><span class="bp">|</span> <span class="o">:=</span> <span class="n">Int.emod_lt</span> <span class="n">a</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℤ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">|</span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Int.emod_lt</span><span class="w"> </span><span class="n">a</span> </pre></div> </div> <p>In an arbitrary ring, an element <span class="math notranslate nohighlight">\(a\)</span> is said to be a <em>unit</em> if it divides
-
@@ -1324,37 +1325,37 @@ We are grateful to Heather Macbeth for suggesting the following moreelegant approach, which avoids definition by cases. We simply add <code class="docutils literal notranslate"><span class="pre">b</span> <span class="pre">/</span> <span class="pre">2</span></code> to <code class="docutils literal notranslate"><span class="pre">a</span></code> before dividing and then subtract it from the remainder.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">div'</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℤ</span><span class="o">)</span> <span class="o">:=</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">/</span> <span class="mi">2</span><span class="o">)</span> <span class="bp">/</span> <span class="n">b</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">div'</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℤ</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="n">b</span> <span class="kd">def</span> <span class="n">mod'</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℤ</span><span class="o">)</span> <span class="o">:=</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">/</span> <span class="mi">2</span><span class="o">)</span> <span class="bp">%</span> <span class="n">b</span> <span class="bp">-</span> <span class="n">b</span> <span class="bp">/</span> <span class="mi">2</span> <span class="kd">def</span><span class="w"> </span><span class="n">mod'</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℤ</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span> <span class="kd">theorem</span> <span class="n">div'_add_mod'</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℤ</span><span class="o">)</span> <span class="o">:</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">div'</span> <span class="n">a</span> <span class="n">b</span> <span class="bp">+</span> <span class="n">mod'</span> <span class="n">a</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">div'</span><span class="o">,</span> <span class="n">mod'</span><span class="o">]</span> <span class="n">linarith</span> <span class="o">[</span><span class="n">Int.ediv_add_emod</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">/</span> <span class="mi">2</span><span class="o">)</span> <span class="n">b</span><span class="o">]</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">div'_add_mod'</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℤ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">div'</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">mod'</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">div'</span><span class="o">,</span><span class="w"> </span><span class="n">mod'</span><span class="o">]</span> <span class="w"> </span><span class="n">linarith</span><span class="w"> </span><span class="o">[</span><span class="n">Int.ediv_add_emod</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="n">b</span><span class="o">]</span> <span class="kd">theorem</span> <span class="n">abs_mod'_le</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℤ</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">b</span><span class="o">)</span> <span class="o">:</span> <span class="bp">|</span><span class="n">mod'</span> <span class="n">a</span> <span class="n">b</span><span class="bp">|</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">/</span> <span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mod'</span><span class="o">,</span> <span class="n">abs_le</span><span class="o">]</span> <span class="n">constructor</span> <span class="bp">·</span> <span class="n">linarith</span> <span class="o">[</span><span class="n">Int.emod_nonneg</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">/</span> <span class="mi">2</span><span class="o">)</span> <span class="n">h.ne'</span><span class="o">]</span> <span class="k">have</span> <span class="o">:=</span> <span class="n">Int.emod_lt_of_pos</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">/</span> <span class="mi">2</span><span class="o">)</span> <span class="n">h</span> <span class="k">have</span> <span class="o">:=</span> <span class="n">Int.ediv_add_emod</span> <span class="n">b</span> <span class="mi">2</span> <span class="k">have</span> <span class="o">:=</span> <span class="n">Int.emod_lt_of_pos</span> <span class="n">b</span> <span class="n">zero_lt_two</span> <span class="n">linarith</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">abs_mod'_le</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℤ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">|</span><span class="n">mod'</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="bp">|</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mod'</span><span class="o">,</span><span class="w"> </span><span class="n">abs_le</span><span class="o">]</span> <span class="w"> </span><span class="n">constructor</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">linarith</span><span class="w"> </span><span class="o">[</span><span class="n">Int.emod_nonneg</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="n">h.ne'</span><span class="o">]</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Int.emod_lt_of_pos</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Int.ediv_add_emod</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="mi">2</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Int.emod_lt_of_pos</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">zero_lt_two</span> <span class="w"> </span><span class="n">linarith</span> </pre></div> </div> <p>Note the use of our old friend, <code class="docutils literal notranslate"><span class="pre">linarith</span></code>. We will also need to express <code class="docutils literal notranslate"><span class="pre">mod'</span></code> in terms of <code class="docutils literal notranslate"><span class="pre">div'</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">mod'_eq</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℤ</span><span class="o">)</span> <span class="o">:</span> <span class="n">mod'</span> <span class="n">a</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">-</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">div'</span> <span class="n">a</span> <span class="n">b</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">linarith</span> <span class="o">[</span><span class="n">div'_add_mod'</span> <span class="n">a</span> <span class="n">b</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">mod'_eq</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℤ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">mod'</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">div'</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">linarith</span><span class="w"> </span><span class="o">[</span><span class="n">div'_add_mod'</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="o">]</span> </pre></div> </div> <p>We will use the fact that <span class="math notranslate nohighlight">\(x^2 + y^2\)</span> is equal to zero if and only if <span class="math notranslate nohighlight">\(x\)</span> and <span class="math notranslate nohighlight">\(y\)</span> are both zero. As an exercise, we ask you to prove that this holds in any ordered ring.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">sq_add_sq_eq_zero</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">LinearOrderedRing</span> <span class="n">α</span><span class="o">]</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">α</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="n">y</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">=</span> <span class="mi">0</span> <span class="bp">↔</span> <span class="n">x</span> <span class="bp">=</span> <span class="mi">0</span> <span class="bp">∧</span> <span class="n">y</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">sq_add_sq_eq_zero</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">LinearOrderedRing</span><span class="w"> </span><span class="n">α</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>We will put all the remaining definitions and theorems in this section
-
@@ -1362,33 +1363,33 @@ in the <code class="docutils literal notranslate"><span class="pre">GaussInt</span></code> namespace.First, we define the <code class="docutils literal notranslate"><span class="pre">norm</span></code> function and ask you to establish some of its properties. The proofs are all short.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">norm</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">:=</span> <span class="n">x.re</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="n">x.im</span> <span class="bp">^</span> <span class="mi">2</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">x.re</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">x.im</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span> <span class="kd">@[</span><span class="n">simp</span><span class="kd">]</span> <span class="kd">theorem</span> <span class="n">norm_nonneg</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">norm</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">theorem</span> <span class="n">norm_eq_zero</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">:</span> <span class="n">norm</span> <span class="n">x</span> <span class="bp">=</span> <span class="mi">0</span> <span class="bp">↔</span> <span class="n">x</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">theorem</span> <span class="n">norm_pos</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">norm</span> <span class="n">x</span> <span class="bp">↔</span> <span class="n">x</span> <span class="bp">≠</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">theorem</span> <span class="n">norm_mul</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">:</span> <span class="n">norm</span> <span class="o">(</span><span class="n">x</span> <span class="bp">*</span> <span class="n">y</span><span class="o">)</span> <span class="bp">=</span> <span class="n">norm</span> <span class="n">x</span> <span class="bp">*</span> <span class="n">norm</span> <span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">norm_nonneg</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">norm_eq_zero</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">norm_pos</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">norm_mul</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Next we define the conjugate function:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">conj</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">:</span> <span class="n">GaussInt</span> <span class="o">:=</span> <span class="o">⟨</span><span class="n">x.re</span><span class="o">,</span> <span class="bp">-</span><span class="n">x.im</span><span class="o">⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">conj</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">⟨</span><span class="n">x.re</span><span class="o">,</span><span class="w"> </span><span class="bp">-</span><span class="n">x.im</span><span class="o">⟩</span> <span class="kd">@[</span><span class="n">simp</span><span class="kd">]</span> <span class="kd">theorem</span> <span class="n">conj_re</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">conj</span> <span class="n">x</span><span class="o">)</span><span class="bp">.</span><span class="n">re</span> <span class="bp">=</span> <span class="n">x.re</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">conj_re</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">conj</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="bp">.</span><span class="n">re</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x.re</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">@[</span><span class="n">simp</span><span class="kd">]</span> <span class="kd">theorem</span> <span class="n">conj_im</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">conj</span> <span class="n">x</span><span class="o">)</span><span class="bp">.</span><span class="n">im</span> <span class="bp">=</span> <span class="bp">-</span><span class="n">x.im</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">conj_im</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">conj</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="bp">.</span><span class="n">im</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">-</span><span class="n">x.im</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">theorem</span> <span class="n">norm_conj</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">:</span> <span class="n">norm</span> <span class="o">(</span><span class="n">conj</span> <span class="n">x</span><span class="o">)</span> <span class="bp">=</span> <span class="n">norm</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="o">[</span><span class="n">norm</span><span class="o">]</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">norm_conj</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="o">(</span><span class="n">conj</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">norm</span><span class="o">]</span> </pre></div> </div> <p>Finally, we define division for the Gaussian integers
-
@@ -1401,23 +1402,23 @@ \[\frac{ac + bd}{c^2 + d^2} \quad \text{and} \quad \frac{bc -ad}{c^2+d^2},\]</div><p>respectively. Here the numerators are the real and imaginary parts of <span class="math notranslate nohighlight">\((a + bi) (c - di)\)</span>, and the denominators are both equal to the norm of <span class="math notranslate nohighlight">\(c + di\)</span>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span> <span class="o">:</span> <span class="n">Div</span> <span class="n">GaussInt</span> <span class="o">:=</span> <span class="o">⟨</span><span class="k">fun</span> <span class="n">x</span> <span class="n">y</span> <span class="bp">↦</span> <span class="o">⟨</span><span class="n">Int.div'</span> <span class="o">(</span><span class="n">x</span> <span class="bp">*</span> <span class="n">conj</span> <span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">re</span> <span class="o">(</span><span class="n">norm</span> <span class="n">y</span><span class="o">),</span> <span class="n">Int.div'</span> <span class="o">(</span><span class="n">x</span> <span class="bp">*</span> <span class="n">conj</span> <span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">im</span> <span class="o">(</span><span class="n">norm</span> <span class="n">y</span><span class="o">)⟩⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Div</span><span class="w"> </span><span class="n">GaussInt</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">⟨</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">⟨</span><span class="n">Int.div'</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">conj</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">re</span><span class="w"> </span><span class="o">(</span><span class="n">norm</span><span class="w"> </span><span class="n">y</span><span class="o">),</span><span class="w"> </span><span class="n">Int.div'</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">conj</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">im</span><span class="w"> </span><span class="o">(</span><span class="n">norm</span><span class="w"> </span><span class="n">y</span><span class="o">)⟩⟩</span> </pre></div> </div> <p>Having defined <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">/</span> <span class="pre">y</span></code>, We define <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">%</span> <span class="pre">y</span></code> to be the remainder, <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">-</span> <span class="pre">(x</span> <span class="pre">/</span> <span class="pre">y)</span> <span class="pre">*</span> <span class="pre">y</span></code>. As above, we record the definitions in the theorems <code class="docutils literal notranslate"><span class="pre">div_def</span></code> and <code class="docutils literal notranslate"><span class="pre">mod_def</span></code> so that we can use them with <code class="docutils literal notranslate"><span class="pre">simp</span></code> and <code class="docutils literal notranslate"><span class="pre">rewrite</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span> <span class="o">:</span> <span class="n">Mod</span> <span class="n">GaussInt</span> <span class="o">:=</span> <span class="o">⟨</span><span class="k">fun</span> <span class="n">x</span> <span class="n">y</span> <span class="bp">↦</span> <span class="n">x</span> <span class="bp">-</span> <span class="n">y</span> <span class="bp">*</span> <span class="o">(</span><span class="n">x</span> <span class="bp">/</span> <span class="n">y</span><span class="o">)⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Mod</span><span class="w"> </span><span class="n">GaussInt</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">⟨</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="n">y</span><span class="o">)⟩</span> <span class="kd">theorem</span> <span class="n">div_def</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">/</span> <span class="n">y</span> <span class="bp">=</span> <span class="o">⟨</span><span class="n">Int.div'</span> <span class="o">(</span><span class="n">x</span> <span class="bp">*</span> <span class="n">conj</span> <span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">re</span> <span class="o">(</span><span class="n">norm</span> <span class="n">y</span><span class="o">),</span> <span class="n">Int.div'</span> <span class="o">(</span><span class="n">x</span> <span class="bp">*</span> <span class="n">conj</span> <span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">im</span> <span class="o">(</span><span class="n">norm</span> <span class="n">y</span><span class="o">)⟩</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">div_def</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">⟨</span><span class="n">Int.div'</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">conj</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">re</span><span class="w"> </span><span class="o">(</span><span class="n">norm</span><span class="w"> </span><span class="n">y</span><span class="o">),</span><span class="w"> </span><span class="n">Int.div'</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">conj</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">im</span><span class="w"> </span><span class="o">(</span><span class="n">norm</span><span class="w"> </span><span class="n">y</span><span class="o">)⟩</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">theorem</span> <span class="n">mod_def</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">%</span> <span class="n">y</span> <span class="bp">=</span> <span class="n">x</span> <span class="bp">-</span> <span class="n">y</span> <span class="bp">*</span> <span class="o">(</span><span class="n">x</span> <span class="bp">/</span> <span class="n">y</span><span class="o">)</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">mod_def</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> </pre></div> </div> <p>These definitions immediately yield <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">=</span> <span class="pre">y</span> <span class="pre">*</span> <span class="pre">(x</span> <span class="pre">/</span> <span class="pre">y)</span> <span class="pre">+</span> <span class="pre">x</span> <span class="pre">%</span> <span class="pre">y</span></code> for every
-
@@ -1445,24 +1446,24 @@ <p>Dividing through by <code class="docutils literal notranslate"><span class="pre">norm</span> <span class="pre">y</span></code> we have <code class="docutils literal notranslate"><span class="pre">norm</span> <span class="pre">(x</span> <span class="pre">%</span> <span class="pre">y)</span> <span class="pre">≤</span> <span class="pre">(norm</span> <span class="pre">y)</span> <span class="pre">/</span> <span class="pre">2</span> <span class="pre"><</span> <span class="pre">norm</span> <span class="pre">y</span></code>,as required.</p> <p>This messy calculation is carried out in the next proof. We encourage you to step through the details and see if you can find a nicer argument.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">norm_mod_lt</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">{</span><span class="n">y</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">}</span> <span class="o">(</span><span class="n">hy</span> <span class="o">:</span> <span class="n">y</span> <span class="bp">≠</span> <span class="mi">0</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">x</span> <span class="bp">%</span> <span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">norm</span> <span class="bp"><</span> <span class="n">y.norm</span> <span class="o">:=</span> <span class="kd">by</span> <span class="k">have</span> <span class="n">norm_y_pos</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">norm</span> <span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rwa</span> <span class="o">[</span><span class="n">norm_pos</span><span class="o">]</span> <span class="k">have</span> <span class="n">H1</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">%</span> <span class="n">y</span> <span class="bp">*</span> <span class="n">conj</span> <span class="n">y</span> <span class="bp">=</span> <span class="o">⟨</span><span class="n">Int.mod'</span> <span class="o">(</span><span class="n">x</span> <span class="bp">*</span> <span class="n">conj</span> <span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">re</span> <span class="o">(</span><span class="n">norm</span> <span class="n">y</span><span class="o">),</span> <span class="n">Int.mod'</span> <span class="o">(</span><span class="n">x</span> <span class="bp">*</span> <span class="n">conj</span> <span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">im</span> <span class="o">(</span><span class="n">norm</span> <span class="n">y</span><span class="o">)⟩</span> <span class="bp">·</span> <span class="n">ext</span> <span class="bp"><;></span> <span class="n">simp</span> <span class="o">[</span><span class="n">Int.mod'_eq</span><span class="o">,</span> <span class="n">mod_def</span><span class="o">,</span> <span class="n">div_def</span><span class="o">,</span> <span class="n">norm</span><span class="o">]</span> <span class="bp"><;></span> <span class="n">ring</span> <span class="k">have</span> <span class="n">H2</span> <span class="o">:</span> <span class="n">norm</span> <span class="o">(</span><span class="n">x</span> <span class="bp">%</span> <span class="n">y</span><span class="o">)</span> <span class="bp">*</span> <span class="n">norm</span> <span class="n">y</span> <span class="bp">≤</span> <span class="n">norm</span> <span class="n">y</span> <span class="bp">/</span> <span class="mi">2</span> <span class="bp">*</span> <span class="n">norm</span> <span class="n">y</span> <span class="bp">·</span> <span class="k">calc</span> <span class="n">norm</span> <span class="o">(</span><span class="n">x</span> <span class="bp">%</span> <span class="n">y</span><span class="o">)</span> <span class="bp">*</span> <span class="n">norm</span> <span class="n">y</span> <span class="bp">=</span> <span class="n">norm</span> <span class="o">(</span><span class="n">x</span> <span class="bp">%</span> <span class="n">y</span> <span class="bp">*</span> <span class="n">conj</span> <span class="n">y</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="n">only</span> <span class="o">[</span><span class="n">norm_mul</span><span class="o">,</span> <span class="n">norm_conj</span><span class="o">]</span> <span class="n">_</span> <span class="bp">=</span> <span class="bp">|</span><span class="n">Int.mod'</span> <span class="o">(</span><span class="n">x.re</span> <span class="bp">*</span> <span class="n">y.re</span> <span class="bp">+</span> <span class="n">x.im</span> <span class="bp">*</span> <span class="n">y.im</span><span class="o">)</span> <span class="o">(</span><span class="n">norm</span> <span class="n">y</span><span class="o">)</span><span class="bp">|</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="bp">|</span><span class="n">Int.mod'</span> <span class="o">(</span><span class="bp">-</span><span class="o">(</span><span class="n">x.re</span> <span class="bp">*</span> <span class="n">y.im</span><span class="o">)</span> <span class="bp">+</span> <span class="n">x.im</span> <span class="bp">*</span> <span class="n">y.re</span><span class="o">)</span> <span class="o">(</span><span class="n">norm</span> <span class="n">y</span><span class="o">)</span><span class="bp">|</span> <span class="bp">^</span> <span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="o">[</span><span class="n">H1</span><span class="o">,</span> <span class="n">norm</span><span class="o">,</span> <span class="n">sq_abs</span><span class="o">]</span> <span class="n">_</span> <span class="bp">≤</span> <span class="o">(</span><span class="n">y.norm</span> <span class="bp">/</span> <span class="mi">2</span><span class="o">)</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="o">(</span><span class="n">y.norm</span> <span class="bp">/</span> <span class="mi">2</span><span class="o">)</span> <span class="bp">^</span> <span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">gcongr</span> <span class="bp"><;></span> <span class="n">apply</span> <span class="n">Int.abs_mod'_le</span> <span class="n">_</span> <span class="n">_</span> <span class="n">norm_y_pos</span> <span class="n">_</span> <span class="bp">=</span> <span class="n">norm</span> <span class="n">y</span> <span class="bp">/</span> <span class="mi">2</span> <span class="bp">*</span> <span class="o">(</span><span class="n">norm</span> <span class="n">y</span> <span class="bp">/</span> <span class="mi">2</span> <span class="bp">*</span> <span class="mi">2</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ring</span> <span class="n">_</span> <span class="bp">≤</span> <span class="n">norm</span> <span class="n">y</span> <span class="bp">/</span> <span class="mi">2</span> <span class="bp">*</span> <span class="n">norm</span> <span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">gcongr</span><span class="bp">;</span> <span class="n">apply</span> <span class="n">Int.ediv_mul_le</span><span class="bp">;</span> <span class="n">norm_num</span> <span class="k">calc</span> <span class="n">norm</span> <span class="o">(</span><span class="n">x</span> <span class="bp">%</span> <span class="n">y</span><span class="o">)</span> <span class="bp">≤</span> <span class="n">norm</span> <span class="n">y</span> <span class="bp">/</span> <span class="mi">2</span> <span class="o">:=</span> <span class="n">le_of_mul_le_mul_right</span> <span class="n">H2</span> <span class="n">norm_y_pos</span> <span class="n">_</span> <span class="bp"><</span> <span class="n">norm</span> <span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">Int.ediv_lt_of_lt_mul</span> <span class="bp">·</span> <span class="n">norm_num</span> <span class="bp">·</span> <span class="n">linarith</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">norm_mod_lt</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hy</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">norm</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y.norm</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">norm_y_pos</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">rwa</span><span class="w"> </span><span class="o">[</span><span class="n">norm_pos</span><span class="o">]</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">H1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">conj</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">⟨</span><span class="n">Int.mod'</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">conj</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">re</span><span class="w"> </span><span class="o">(</span><span class="n">norm</span><span class="w"> </span><span class="n">y</span><span class="o">),</span><span class="w"> </span><span class="n">Int.mod'</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">conj</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">im</span><span class="w"> </span><span class="o">(</span><span class="n">norm</span><span class="w"> </span><span class="n">y</span><span class="o">)⟩</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">Int.mod'_eq</span><span class="o">,</span><span class="w"> </span><span class="n">mod_def</span><span class="o">,</span><span class="w"> </span><span class="n">div_def</span><span class="o">,</span><span class="w"> </span><span class="n">norm</span><span class="o">]</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">ring</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">H2</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="n">y</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="k">calc</span> <span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">conj</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="n">only</span><span class="w"> </span><span class="o">[</span><span class="n">norm_mul</span><span class="o">,</span><span class="w"> </span><span class="n">norm_conj</span><span class="o">]</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">|</span><span class="n">Int.mod'</span><span class="w"> </span><span class="o">(</span><span class="n">x.re</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y.re</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">x.im</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y.im</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">norm</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="bp">|</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span> <span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="bp">|</span><span class="n">Int.mod'</span><span class="w"> </span><span class="o">(</span><span class="bp">-</span><span class="o">(</span><span class="n">x.re</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y.im</span><span class="o">)</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">x.im</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y.re</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">norm</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="bp">|</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">H1</span><span class="o">,</span><span class="w"> </span><span class="n">norm</span><span class="o">,</span><span class="w"> </span><span class="n">sq_abs</span><span class="o">]</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="o">(</span><span class="n">y.norm</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="o">(</span><span class="n">y.norm</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">gcongr</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">Int.abs_mod'_le</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">norm_y_pos</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">norm</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">ring</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">gcongr</span><span class="bp">;</span><span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">Int.ediv_mul_le</span><span class="bp">;</span><span class="w"> </span><span class="n">norm_num</span> <span class="w"> </span><span class="k">calc</span><span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">le_of_mul_le_mul_right</span><span class="w"> </span><span class="n">H2</span><span class="w"> </span><span class="n">norm_y_pos</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">norm</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">Int.ediv_lt_of_lt_mul</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">norm_num</span> <span class="w"> </span><span class="bp">·</span><span class="w"> </span><span class="n">linarith</span> </pre></div> </div> <p>We are in the home stretch. Our <code class="docutils literal notranslate"><span class="pre">norm</span></code> function maps Gaussian integers to
-
@@ -1472,26 +1473,26 @@ <code class="docutils literal notranslate"><span class="pre">Int.natAbs</span></code>, which maps integers to the natural numbers.The first of the next two lemmas establishes that mapping the norm to the natural numbers and back to the integers does not change the value. The second one re-expresses the fact that the norm is decreasing.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">coe_natAbs_norm</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">x.norm.natAbs</span> <span class="o">:</span> <span class="n">ℤ</span><span class="o">)</span> <span class="bp">=</span> <span class="n">x.norm</span> <span class="o">:=</span> <span class="n">Int.natAbs_of_nonneg</span> <span class="o">(</span><span class="n">norm_nonneg</span> <span class="n">_</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">coe_natAbs_norm</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">x.norm.natAbs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℤ</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x.norm</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Int.natAbs_of_nonneg</span><span class="w"> </span><span class="o">(</span><span class="n">norm_nonneg</span><span class="w"> </span><span class="n">_</span><span class="o">)</span> <span class="kd">theorem</span> <span class="n">natAbs_norm_mod_lt</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">(</span><span class="n">hy</span> <span class="o">:</span> <span class="n">y</span> <span class="bp">≠</span> <span class="mi">0</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">x</span> <span class="bp">%</span> <span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">norm.natAbs</span> <span class="bp"><</span> <span class="n">y.norm.natAbs</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">Int.ofNat_lt.1</span> <span class="n">simp</span> <span class="n">only</span> <span class="o">[</span><span class="n">Int.natCast_natAbs</span><span class="o">,</span> <span class="n">abs_of_nonneg</span><span class="o">,</span> <span class="n">norm_nonneg</span><span class="o">]</span> <span class="n">exact</span> <span class="n">norm_mod_lt</span> <span class="n">x</span> <span class="n">hy</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">natAbs_norm_mod_lt</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hy</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="bp">.</span><span class="n">norm.natAbs</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">y.norm.natAbs</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">Int.ofNat_lt</span><span class="bp">.</span><span class="mi">1</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="n">only</span><span class="w"> </span><span class="o">[</span><span class="n">Int.natCast_natAbs</span><span class="o">,</span><span class="w"> </span><span class="n">abs_of_nonneg</span><span class="o">,</span><span class="w"> </span><span class="n">norm_nonneg</span><span class="o">]</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">norm_mod_lt</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">hy</span> </pre></div> </div> <p>We also need to establish the second key property of the norm function on a Euclidean domain.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">not_norm_mul_left_lt_norm</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">{</span><span class="n">y</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">}</span> <span class="o">(</span><span class="n">hy</span> <span class="o">:</span> <span class="n">y</span> <span class="bp">≠</span> <span class="mi">0</span><span class="o">)</span> <span class="o">:</span> <span class="bp">¬</span><span class="o">(</span><span class="n">norm</span> <span class="o">(</span><span class="n">x</span> <span class="bp">*</span> <span class="n">y</span><span class="o">))</span><span class="bp">.</span><span class="n">natAbs</span> <span class="bp"><</span> <span class="o">(</span><span class="n">norm</span> <span class="n">x</span><span class="o">)</span><span class="bp">.</span><span class="n">natAbs</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">not_lt_of_ge</span> <span class="n">rw</span> <span class="o">[</span><span class="n">norm_mul</span><span class="o">,</span> <span class="n">Int.natAbs_mul</span><span class="o">]</span> <span class="n">apply</span> <span class="n">le_mul_of_one_le_right</span> <span class="o">(</span><span class="n">Nat.zero_le</span> <span class="n">_</span><span class="o">)</span> <span class="n">apply</span> <span class="n">Int.ofNat_le.1</span> <span class="n">rw</span> <span class="o">[</span><span class="n">coe_natAbs_norm</span><span class="o">]</span> <span class="n">exact</span> <span class="n">Int.add_one_le_of_lt</span> <span class="o">((</span><span class="n">norm_pos</span> <span class="n">_</span><span class="o">)</span><span class="bp">.</span><span class="n">mpr</span> <span class="n">hy</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">not_norm_mul_left_lt_norm</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hy</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">¬</span><span class="o">(</span><span class="n">norm</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="o">))</span><span class="bp">.</span><span class="n">natAbs</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="o">(</span><span class="n">norm</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="bp">.</span><span class="n">natAbs</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">not_lt_of_ge</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">norm_mul</span><span class="o">,</span><span class="w"> </span><span class="n">Int.natAbs_mul</span><span class="o">]</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">le_mul_of_one_le_right</span><span class="w"> </span><span class="o">(</span><span class="n">Nat.zero_le</span><span class="w"> </span><span class="n">_</span><span class="o">)</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">Int.ofNat_le</span><span class="bp">.</span><span class="mi">1</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">coe_natAbs_norm</span><span class="o">]</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">Int.add_one_le_of_lt</span><span class="w"> </span><span class="o">((</span><span class="n">norm_pos</span><span class="w"> </span><span class="n">_</span><span class="o">)</span><span class="bp">.</span><span class="n">mpr</span><span class="w"> </span><span class="n">hy</span><span class="o">)</span> </pre></div> </div> <p>We can now put it together to show that the Gaussian integers are an
-
@@ -1504,25 +1505,25 @@ Comparing the values of a norm function that returns natural numbers isjust one instance of such a measure, and in that case, the required properties are the theorems <code class="docutils literal notranslate"><span class="pre">natAbs_norm_mod_lt</span></code> and <code class="docutils literal notranslate"><span class="pre">not_norm_mul_left_lt_norm</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span> <span class="o">:</span> <span class="n">EuclideanDomain</span> <span class="n">GaussInt</span> <span class="o">:=</span> <span class="o">{</span> <span class="n">GaussInt.instCommRing</span> <span class="k">with</span> <span class="n">quotient</span> <span class="o">:=</span> <span class="o">(</span><span class="bp">·</span> <span class="bp">/</span> <span class="bp">·</span><span class="o">)</span> <span class="n">remainder</span> <span class="o">:=</span> <span class="o">(</span><span class="bp">·</span> <span class="bp">%</span> <span class="bp">·</span><span class="o">)</span> <span class="n">quotient_mul_add_remainder_eq</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">x</span> <span class="n">y</span> <span class="bp">↦</span> <span class="kd">by</span> <span class="n">simp</span> <span class="n">only</span><span class="bp">;</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mod_def</span><span class="o">,</span> <span class="n">add_comm</span><span class="o">]</span> <span class="bp">;</span> <span class="n">ring</span> <span class="n">quotient_zero</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="kd">by</span> <span class="n">simp</span> <span class="o">[</span><span class="n">div_def</span><span class="o">,</span> <span class="n">norm</span><span class="o">,</span> <span class="n">Int.div'</span><span class="o">]</span> <span class="n">rfl</span> <span class="n">r</span> <span class="o">:=</span> <span class="o">(</span><span class="n">measure</span> <span class="o">(</span><span class="n">Int.natAbs</span> <span class="bp">∘</span> <span class="n">norm</span><span class="o">))</span><span class="bp">.</span><span class="mi">1</span> <span class="n">r_wellFounded</span> <span class="o">:=</span> <span class="o">(</span><span class="n">measure</span> <span class="o">(</span><span class="n">Int.natAbs</span> <span class="bp">∘</span> <span class="n">norm</span><span class="o">))</span><span class="bp">.</span><span class="mi">2</span> <span class="n">remainder_lt</span> <span class="o">:=</span> <span class="n">natAbs_norm_mod_lt</span> <span class="n">mul_left_not_lt</span> <span class="o">:=</span> <span class="n">not_norm_mul_left_lt_norm</span> <span class="o">}</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">EuclideanDomain</span><span class="w"> </span><span class="n">GaussInt</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">GaussInt.instCommRing</span><span class="w"> </span><span class="k">with</span> <span class="w"> </span><span class="n">quotient</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="bp">·</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="bp">·</span><span class="o">)</span> <span class="w"> </span><span class="n">remainder</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="bp">·</span><span class="w"> </span><span class="bp">%</span><span class="w"> </span><span class="bp">·</span><span class="o">)</span> <span class="w"> </span><span class="n">quotient_mul_add_remainder_eq</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="n">only</span><span class="bp">;</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mod_def</span><span class="o">,</span><span class="w"> </span><span class="n">add_comm</span><span class="o">]</span><span class="w"> </span><span class="bp">;</span><span class="w"> </span><span class="n">ring</span> <span class="w"> </span><span class="n">quotient_zero</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">div_def</span><span class="o">,</span><span class="w"> </span><span class="n">norm</span><span class="o">,</span><span class="w"> </span><span class="n">Int.div'</span><span class="o">]</span> <span class="w"> </span><span class="n">rfl</span> <span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="n">measure</span><span class="w"> </span><span class="o">(</span><span class="n">Int.natAbs</span><span class="w"> </span><span class="bp">∘</span><span class="w"> </span><span class="n">norm</span><span class="o">))</span><span class="bp">.</span><span class="mi">1</span> <span class="w"> </span><span class="n">r_wellFounded</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="n">measure</span><span class="w"> </span><span class="o">(</span><span class="n">Int.natAbs</span><span class="w"> </span><span class="bp">∘</span><span class="w"> </span><span class="n">norm</span><span class="o">))</span><span class="bp">.</span><span class="mi">2</span> <span class="w"> </span><span class="n">remainder_lt</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">natAbs_norm_mod_lt</span> <span class="w"> </span><span class="n">mul_left_not_lt</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">not_norm_mul_left_lt_norm</span><span class="w"> </span><span class="o">}</span> </pre></div> </div> <p>An immediate payoff is that we now know that, in the Gaussian integers, the notions of being prime and being irreducible coincide.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">GaussInt</span><span class="o">)</span> <span class="o">:</span> <span class="n">Irreducible</span> <span class="n">x</span> <span class="bp">↔</span> <span class="n">Prime</span> <span class="n">x</span> <span class="o">:=</span> <span class="n">irreducible_iff_prime</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaussInt</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Irreducible</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">Prime</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">irreducible_iff_prime</span> </pre></div> </div> </section>
-
-
-
@@ -1,3 +1,5 @@<!DOCTYPE html> <html class="writer-html5" lang="en" data-content_root="./"> <head>
-
@@ -6,17 +8,16 @@<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>7. Hierarchies — Mathematics in Lean 0.1 documentation</title> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=80d5e7a1" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=86f27845" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" /> <link rel="stylesheet" type="text/css" href="_static/css/custom.css?v=0731ccc3" /> <link rel="shortcut icon" href="_static/favicon.ico"/> <script src="_static/jquery.js?v=8dae8fb0"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=888ff710"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script src="_static/jquery.js?v=5d32c60e"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=9bcbadda"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script src="_static/js/theme.js"></script> <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" />
-
@@ -112,9 +113,9 @@ <span id="section-hierarchies-basics"></span><h2><span class="section-number">7.1. </span>Basics<a class="headerlink" href="#basics" title="Link to this heading"></a></h2><p>At the very bottom of all hierarchies in Lean, we find data-carrying classes. The following class records that the given type <code class="docutils literal notranslate"><span class="pre">α</span></code> is endowed with a distinguished element called <code class="docutils literal notranslate"><span class="pre">one</span></code>. At this stage, it has no property at all.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span> <span class="n">One₁</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="n">where</span> <span class="sd">/-- The element one -/</span> <span class="n">one</span> <span class="o">:</span> <span class="n">α</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span><span class="w"> </span><span class="n">One₁</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="sd">/-- The element one -/</span> <span class="w"> </span><span class="n">one</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span> </pre></div> </div> <p>Since we’ll make a much heavier use of classes in this chapter, we need to understand some
-
@@ -126,18 +127,18 @@ as long as they are marked as instance-implicit, i.e. appear between square brackets.Those two effects could also have been achieved using the <code class="docutils literal notranslate"><span class="pre">structure</span></code> command with <code class="docutils literal notranslate"><span class="pre">class</span></code> attribute, i.e. writing <code class="docutils literal notranslate"><span class="pre">@[class]</span> <span class="pre">structure</span></code> instance of <code class="docutils literal notranslate"><span class="pre">class</span></code>. But the class command also ensures that <code class="docutils literal notranslate"><span class="pre">One₁</span> <span class="pre">α</span></code> appears as an instance-implicit argument in its own fields. Compare:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="n">One₁.one</span> <span class="c1">-- One₁.one {α : Type} [self : One₁ α] : α</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="n">One₁.one</span><span class="w"> </span><span class="c1">-- One₁.one {α : Type} [self : One₁ α] : α</span> <span class="kd">@[</span><span class="n">class</span><span class="kd">]</span> <span class="kd">structure</span> <span class="n">One₂</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="n">where</span> <span class="sd">/-- The element one -/</span> <span class="n">one</span> <span class="o">:</span> <span class="n">α</span> <span class="kd">@[</span><span class="n">class</span><span class="kd">]</span><span class="w"> </span><span class="kd">structure</span><span class="w"> </span><span class="n">One₂</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="sd">/-- The element one -/</span> <span class="w"> </span><span class="n">one</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span> <span class="k">#check</span> <span class="n">One₂.one</span> <span class="k">#check</span><span class="w"> </span><span class="n">One₂.one</span> </pre></div> </div> <p>In the second check, we can see that <code class="docutils literal notranslate"><span class="pre">self</span> <span class="pre">:</span> <span class="pre">One₂</span> <span class="pre">α</span></code> is an explicit argument. Let us make sure the first version is indeed usable without any explicit argument.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">One₁</span> <span class="n">α</span><span class="o">]</span> <span class="o">:</span> <span class="n">α</span> <span class="o">:=</span> <span class="n">One₁.one</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">One₁</span><span class="w"> </span><span class="n">α</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">One₁.one</span> </pre></div> </div> <p>Remark: in the above example, the argument <code class="docutils literal notranslate"><span class="pre">One₁</span> <span class="pre">α</span></code> is marked as instance-implicit,
-
@@ -151,7 +152,7 @@ <code class="docutils literal notranslate"><span class="pre">typeclass</span> <span class="pre">instance</span> <span class="pre">problem</span> <span class="pre">is</span> <span class="pre">stuck,</span> <span class="pre">it</span> <span class="pre">is</span> <span class="pre">often</span> <span class="pre">due</span> <span class="pre">to</span> <span class="pre">metavariables</span> <span class="pre">One₁</span> <span class="pre">(?m.263</span> <span class="pre">α)</span></code>where <code class="docutils literal notranslate"><span class="pre">?m.263</span> <span class="pre">α</span></code> means “some type depending on <code class="docutils literal notranslate"><span class="pre">α</span></code>” (and 263 is simply an auto-generated index that would be useful to distinguish between several unknown things). Another way to avoid this issue would be to use a type annotation, as in:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">One₁</span> <span class="n">α</span><span class="o">]</span> <span class="o">:=</span> <span class="o">(</span><span class="n">One₁.one</span> <span class="o">:</span> <span class="n">α</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">One₁</span><span class="w"> </span><span class="n">α</span><span class="o">]</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="n">One₁.one</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span> </pre></div> </div> <p>You may have already encountered that issue when playing with limits of sequences
-
@@ -163,29 +164,29 @@ with the builtin notation for <code class="docutils literal notranslate"><span class="pre">1</span></code>, we will use <code class="docutils literal notranslate"><span class="pre">𝟙</span></code>. This is achieved by the followingcommand where the first line tells Lean to use the documentation of <code class="docutils literal notranslate"><span class="pre">One₁.one</span></code> as documentation for the symbol <code class="docutils literal notranslate"><span class="pre">𝟙</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">@[</span><span class="n">inherit_doc</span><span class="kd">]</span> <span class="kd">notation</span> <span class="s2">"𝟙"</span> <span class="bp">=></span> <span class="n">One₁.one</span> <span class="kd">notation</span><span class="w"> </span><span class="s2">"𝟙"</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="n">One₁.one</span> <span class="kd">example</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">}</span> <span class="o">[</span><span class="n">One₁</span> <span class="n">α</span><span class="o">]</span> <span class="o">:</span> <span class="n">α</span> <span class="o">:=</span> <span class="mi">𝟙</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">One₁</span><span class="w"> </span><span class="n">α</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">𝟙</span> <span class="kd">example</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">}</span> <span class="o">[</span><span class="n">One₁</span> <span class="n">α</span><span class="o">]</span> <span class="o">:</span> <span class="o">(</span><span class="mi">𝟙</span> <span class="o">:</span> <span class="n">α</span><span class="o">)</span> <span class="bp">=</span> <span class="mi">𝟙</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">One₁</span><span class="w"> </span><span class="n">α</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="mi">𝟙</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">𝟙</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">rfl</span> </pre></div> </div> <p>We now want a data-carrying class recording a binary operation. We don’t want to choose between addition and multiplication for now so we’ll use diamond.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span> <span class="n">Dia₁</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="n">where</span> <span class="n">dia</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">α</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span><span class="w"> </span><span class="n">Dia₁</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">dia</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span> <span class="kd">infixl</span><span class="o">:</span><span class="mi">70</span> <span class="s2">" ⋄ "</span> <span class="bp">=></span> <span class="n">Dia₁.dia</span> <span class="kd">infixl</span><span class="o">:</span><span class="mi">70</span><span class="w"> </span><span class="s2">" ⋄ "</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="n">Dia₁.dia</span> </pre></div> </div> <p>As in the <code class="docutils literal notranslate"><span class="pre">One₁</span></code> example, the operation has no property at all at this stage. Let us now define the class of semigroup structures where the operation is denoted by <code class="docutils literal notranslate"><span class="pre">⋄</span></code>. For now, we define it by hand as a structure with two fields, a <code class="docutils literal notranslate"><span class="pre">Dia₁</span></code> instance and some <code class="docutils literal notranslate"><span class="pre">Prop</span></code>-valued field <code class="docutils literal notranslate"><span class="pre">dia_assoc</span></code> asserting associativity of <code class="docutils literal notranslate"><span class="pre">⋄</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span> <span class="n">Semigroup₁</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="n">where</span> <span class="n">toDia₁</span> <span class="o">:</span> <span class="n">Dia₁</span> <span class="n">α</span> <span class="sd">/-- Diamond is associative -/</span> <span class="n">dia_assoc</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">α</span><span class="o">,</span> <span class="n">a</span> <span class="bp">⋄</span> <span class="n">b</span> <span class="bp">⋄</span> <span class="n">c</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">⋄</span> <span class="o">(</span><span class="n">b</span> <span class="bp">⋄</span> <span class="n">c</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span><span class="w"> </span><span class="n">Semigroup₁</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">toDia₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Dia₁</span><span class="w"> </span><span class="n">α</span> <span class="w"> </span><span class="sd">/-- Diamond is associative -/</span> <span class="w"> </span><span class="n">dia_assoc</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">⋄</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">⋄</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">⋄</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">⋄</span><span class="w"> </span><span class="n">c</span><span class="o">)</span> </pre></div> </div> <p>Note that while stating <cite>dia_assoc</cite>, the previously defined field <cite>toDia₁</cite> is in the local
-
@@ -194,19 +195,19 @@ of <cite>a ⋄ b</cite>. However this <cite>toDia₁</cite> field does not become part of the type class instances database.Hence doing <code class="docutils literal notranslate"><span class="pre">example</span> <span class="pre">{α</span> <span class="pre">:</span> <span class="pre">Type}</span> <span class="pre">[Semigroup₁</span> <span class="pre">α]</span> <span class="pre">(a</span> <span class="pre">b</span> <span class="pre">:</span> <span class="pre">α)</span> <span class="pre">:</span> <span class="pre">α</span> <span class="pre">:=</span> <span class="pre">a</span> <span class="pre">⋄</span> <span class="pre">b</span></code> would fail with error message <code class="docutils literal notranslate"><span class="pre">failed</span> <span class="pre">to</span> <span class="pre">synthesize</span> <span class="pre">instance</span> <span class="pre">Dia₁</span> <span class="pre">α</span></code>.</p> <p>We can fix this by adding the <code class="docutils literal notranslate"><span class="pre">instance</span></code> attribute later.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">attribute</span> <span class="o">[</span><span class="kd">instance</span><span class="o">]</span> <span class="n">Semigroup₁.toDia₁</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">attribute</span><span class="w"> </span><span class="o">[</span><span class="kd">instance</span><span class="o">]</span><span class="w"> </span><span class="n">Semigroup₁.toDia₁</span> <span class="kd">example</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">}</span> <span class="o">[</span><span class="n">Semigroup₁</span> <span class="n">α</span><span class="o">]</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">α</span><span class="o">)</span> <span class="o">:</span> <span class="n">α</span> <span class="o">:=</span> <span class="n">a</span> <span class="bp">⋄</span> <span class="n">b</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Semigroup₁</span><span class="w"> </span><span class="n">α</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">⋄</span><span class="w"> </span><span class="n">b</span> </pre></div> </div> <p>Before building up, we need a more convenient way to extend structures than explicitly writing fields like <cite>toDia₁</cite> and adding the instance attribute by hand. The <code class="docutils literal notranslate"><span class="pre">class</span></code> supports this using the <code class="docutils literal notranslate"><span class="pre">extends</span></code> syntax as in:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span> <span class="n">Semigroup₂</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="kd">extends</span> <span class="n">Dia₁</span> <span class="n">α</span> <span class="n">where</span> <span class="sd">/-- Diamond is associative -/</span> <span class="n">dia_assoc</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">α</span><span class="o">,</span> <span class="n">a</span> <span class="bp">⋄</span> <span class="n">b</span> <span class="bp">⋄</span> <span class="n">c</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">⋄</span> <span class="o">(</span><span class="n">b</span> <span class="bp">⋄</span> <span class="n">c</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span><span class="w"> </span><span class="n">Semigroup₂</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="kd">extends</span><span class="w"> </span><span class="n">Dia₁</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="sd">/-- Diamond is associative -/</span> <span class="w"> </span><span class="n">dia_assoc</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">⋄</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">⋄</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">⋄</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">⋄</span><span class="w"> </span><span class="n">c</span><span class="o">)</span> <span class="kd">example</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">}</span> <span class="o">[</span><span class="n">Semigroup₂</span> <span class="n">α</span><span class="o">]</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">α</span><span class="o">)</span> <span class="o">:</span> <span class="n">α</span> <span class="o">:=</span> <span class="n">a</span> <span class="bp">⋄</span> <span class="n">b</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Semigroup₂</span><span class="w"> </span><span class="n">α</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">⋄</span><span class="w"> </span><span class="n">b</span> </pre></div> </div> <p>Note this syntax is also available in the <code class="docutils literal notranslate"><span class="pre">structure</span></code> command, although it that
-
@@ -214,11 +215,11 @@ case it fixes only the hurdle of writing fields such as <cite>toDia₁</cite> since thereis no instance to define in that case.</p> <p>Let us now try to combine a diamond operation and a distinguished one with axioms saying this element is neutral on both sides.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span> <span class="n">DiaOneClass₁</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="kd">extends</span> <span class="n">One₁</span> <span class="n">α</span><span class="o">,</span> <span class="n">Dia₁</span> <span class="n">α</span> <span class="n">where</span> <span class="sd">/-- One is a left neutral element for diamond. -/</span> <span class="n">one_dia</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="o">:</span> <span class="n">α</span><span class="o">,</span> <span class="mi">𝟙</span> <span class="bp">⋄</span> <span class="n">a</span> <span class="bp">=</span> <span class="n">a</span> <span class="sd">/-- One is a right neutral element for diamond -/</span> <span class="n">dia_one</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="o">:</span> <span class="n">α</span><span class="o">,</span> <span class="n">a</span> <span class="bp">⋄</span> <span class="mi">𝟙</span> <span class="bp">=</span> <span class="n">a</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span><span class="w"> </span><span class="n">DiaOneClass₁</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="kd">extends</span><span class="w"> </span><span class="n">One₁</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">Dia₁</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="sd">/-- One is a left neutral element for diamond. -/</span> <span class="w"> </span><span class="n">one_dia</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="mi">𝟙</span><span class="w"> </span><span class="bp">⋄</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span> <span class="w"> </span><span class="sd">/-- One is a right neutral element for diamond -/</span> <span class="w"> </span><span class="n">dia_one</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">⋄</span><span class="w"> </span><span class="mi">𝟙</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span> </pre></div> </div> <p>In the next example, we tell Lean that <code class="docutils literal notranslate"><span class="pre">α</span></code> has a <code class="docutils literal notranslate"><span class="pre">DiaOneClass₁</span></code> structure and state a
-
@@ -228,13 +229,13 @@ is rather terse by default but it can be expanded by clicking on lines ending with black arrows.It includes failed attempts where Lean tried to find instances before having enough type information to succeed. The successful attempts do involve the instances generated by the <code class="docutils literal notranslate"><span class="pre">extends</span></code> syntax.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">set_option</span> <span class="n">trace.Meta.synthInstance</span> <span class="n">true</span> <span class="k">in</span> <span class="kd">example</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">}</span> <span class="o">[</span><span class="n">DiaOneClass₁</span> <span class="n">α</span><span class="o">]</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">α</span><span class="o">)</span> <span class="o">:</span> <span class="kt">Prop</span> <span class="o">:=</span> <span class="n">a</span> <span class="bp">⋄</span> <span class="n">b</span> <span class="bp">=</span> <span class="mi">𝟙</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">set_option</span><span class="w"> </span><span class="n">trace.Meta.synthInstance</span><span class="w"> </span><span class="n">true</span><span class="w"> </span><span class="k">in</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">DiaOneClass₁</span><span class="w"> </span><span class="n">α</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">⋄</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">𝟙</span> </pre></div> </div> <p>Note that we don’t need to include extra fields where combining existing classes. Hence we can define monoids as:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span> <span class="n">Monoid₁</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="kd">extends</span> <span class="n">Semigroup₁</span> <span class="n">α</span><span class="o">,</span> <span class="n">DiaOneClass₁</span> <span class="n">α</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span><span class="w"> </span><span class="n">Monoid₁</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="kd">extends</span><span class="w"> </span><span class="n">Semigroup₁</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">DiaOneClass₁</span><span class="w"> </span><span class="n">α</span> </pre></div> </div> <p>While the above definition seems straightforward, it hides an important subtlety. Both
-
@@ -242,25 +243,25 @@ <code class="docutils literal notranslate"><span class="pre">Semigroup₁</span> <span class="pre">α</span></code> and <code class="docutils literal notranslate"><span class="pre">DiaOneClass₁</span> <span class="pre">α</span></code> extend <code class="docutils literal notranslate"><span class="pre">Dia₁</span> <span class="pre">α</span></code>, so one could fear that havinga <code class="docutils literal notranslate"><span class="pre">Monoid₁</span> <span class="pre">α</span></code> instance gives two unrelated diamond operations on <code class="docutils literal notranslate"><span class="pre">α</span></code>, one coming from a field <code class="docutils literal notranslate"><span class="pre">Monoid₁.toSemigroup₁</span></code> and one coming from a field <code class="docutils literal notranslate"><span class="pre">Monoid₁.toDiaOneClass₁</span></code>.</p> <p>Indeed if we try to build a monoid class by hand using:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span> <span class="n">Monoid₂</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="n">where</span> <span class="n">toSemigroup₁</span> <span class="o">:</span> <span class="n">Semigroup₁</span> <span class="n">α</span> <span class="n">toDiaOneClass₁</span> <span class="o">:</span> <span class="n">DiaOneClass₁</span> <span class="n">α</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span><span class="w"> </span><span class="n">Monoid₂</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">toSemigroup₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Semigroup₁</span><span class="w"> </span><span class="n">α</span> <span class="w"> </span><span class="n">toDiaOneClass₁</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">DiaOneClass₁</span><span class="w"> </span><span class="n">α</span> </pre></div> </div> <p>then we get two completely unrelated diamond operations <code class="docutils literal notranslate"><span class="pre">Monoid₂.toSemigroup₁.toDia₁.dia</span></code> and <code class="docutils literal notranslate"><span class="pre">Monoid₂.toDiaOneClass₁.toDia₁.dia</span></code>.</p> <p>The version generated using the <code class="docutils literal notranslate"><span class="pre">extends</span></code> syntax does not have this defect.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">}</span> <span class="o">[</span><span class="n">Monoid₁</span> <span class="n">α</span><span class="o">]</span> <span class="o">:</span> <span class="o">(</span><span class="n">Monoid₁.toSemigroup₁.toDia₁.dia</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">α</span><span class="o">)</span> <span class="bp">=</span> <span class="n">Monoid₁.toDiaOneClass₁.toDia₁.dia</span> <span class="o">:=</span> <span class="n">rfl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid₁</span><span class="w"> </span><span class="n">α</span><span class="o">]</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="o">(</span><span class="n">Monoid₁.toSemigroup₁.toDia₁.dia</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">Monoid₁.toDiaOneClass₁.toDia₁.dia</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">rfl</span> </pre></div> </div> <p>So the <code class="docutils literal notranslate"><span class="pre">class</span></code> command did some magic for us (and the <code class="docutils literal notranslate"><span class="pre">structure</span></code> command would have done it too). An easy way to see what are the fields of our classes is to check their constructor. Compare:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="c">/-</span><span class="cm"> Monoid₂.mk {α : Type} (toSemigroup₁ : Semigroup₁ α) (toDiaOneClass₁ : DiaOneClass₁ α) : Monoid₂ α -/</span> <span class="k">#check</span> <span class="n">Monoid₂.mk</span> <span class="k">#check</span><span class="w"> </span><span class="n">Monoid₂.mk</span> <span class="c">/-</span><span class="cm"> Monoid₁.mk {α : Type} [toSemigroup₁ : Semigroup₁ α] [toOne₁ : One₁ α] (one_dia : ∀ (a : α), 𝟙 ⋄ a = a) (dia_one : ∀ (a : α), a ⋄ 𝟙 = a) : Monoid₁ α -/</span> <span class="k">#check</span> <span class="n">Monoid₁.mk</span> <span class="k">#check</span><span class="w"> </span><span class="n">Monoid₁.mk</span> </pre></div> </div> <p>So we see that <code class="docutils literal notranslate"><span class="pre">Monoid₁</span></code> takes <code class="docutils literal notranslate"><span class="pre">Semigroup₁</span> <span class="pre">α</span></code> argument as expected but then it won’t
-
@@ -268,50 +269,50 @@ take a would-be overlapping <code class="docutils literal notranslate"><span class="pre">DiaOneClass₁</span> <span class="pre">α</span></code> argument but instead tears it apart and includesonly the non-overlapping parts. And it also auto-generated an instance <code class="docutils literal notranslate"><span class="pre">Monoid₁.toDiaOneClass₁</span></code> which is <em>not</em> a field but has the expected signature which, from the end-user point of view, restores the symmetry between the two extended classes <code class="docutils literal notranslate"><span class="pre">Semigroup₁</span></code> and <code class="docutils literal notranslate"><span class="pre">DiaOneClass₁</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="n">Monoid₁.toSemigroup₁</span> <span class="k">#check</span> <span class="n">Monoid₁.toDiaOneClass₁</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="n">Monoid₁.toSemigroup₁</span> <span class="k">#check</span><span class="w"> </span><span class="n">Monoid₁.toDiaOneClass₁</span> </pre></div> </div> <p>We are now very close to defining groups. We could add to the monoid structure a field asserting the existence of an inverse for every element. But then we would need to work to access these inverses. In practice it is more convenient to add it as data. To optimize reusability, we define a new data-carrying class, and then give it some notation.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span> <span class="n">Inv₁</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="n">where</span> <span class="sd">/-- The inversion function -/</span> <span class="n">inv</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">α</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span><span class="w"> </span><span class="n">Inv₁</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="sd">/-- The inversion function -/</span> <span class="w"> </span><span class="n">inv</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span> <span class="kd">@[</span><span class="n">inherit_doc</span><span class="kd">]</span> <span class="kd">postfix</span><span class="o">:</span><span class="n">max</span> <span class="s2">"⁻¹"</span> <span class="bp">=></span> <span class="n">Inv₁.inv</span> <span class="kd">postfix</span><span class="o">:</span><span class="n">max</span><span class="w"> </span><span class="s2">"⁻¹"</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="n">Inv₁.inv</span> <span class="kd">class</span> <span class="n">Group₁</span> <span class="o">(</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="kd">extends</span> <span class="n">Monoid₁</span> <span class="n">G</span><span class="o">,</span> <span class="n">Inv₁</span> <span class="n">G</span> <span class="n">where</span> <span class="n">inv_dia</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="o">:</span> <span class="n">G</span><span class="o">,</span> <span class="n">a</span><span class="bp">⁻¹</span> <span class="bp">⋄</span> <span class="n">a</span> <span class="bp">=</span> <span class="mi">𝟙</span> <span class="kd">class</span><span class="w"> </span><span class="n">Group₁</span><span class="w"> </span><span class="o">(</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="kd">extends</span><span class="w"> </span><span class="n">Monoid₁</span><span class="w"> </span><span class="n">G</span><span class="o">,</span><span class="w"> </span><span class="n">Inv₁</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">inv_dia</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="bp">⁻¹</span><span class="w"> </span><span class="bp">⋄</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">𝟙</span> </pre></div> </div> <p>The above definition may seem too weak, we only ask that <code class="docutils literal notranslate"><span class="pre">a⁻¹</span></code> is a left-inverse of <code class="docutils literal notranslate"><span class="pre">a</span></code>. But the other side is automatic. In order to prove that, we need a preliminary lemma.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">lemma</span> <span class="n">left_inv_eq_right_inv₁</span> <span class="o">{</span><span class="n">M</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">}</span> <span class="o">[</span><span class="n">Monoid₁</span> <span class="n">M</span><span class="o">]</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">M</span><span class="o">}</span> <span class="o">(</span><span class="n">hba</span> <span class="o">:</span> <span class="n">b</span> <span class="bp">⋄</span> <span class="n">a</span> <span class="bp">=</span> <span class="mi">𝟙</span><span class="o">)</span> <span class="o">(</span><span class="n">hac</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">⋄</span> <span class="n">c</span> <span class="bp">=</span> <span class="mi">𝟙</span><span class="o">)</span> <span class="o">:</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">c</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="bp">←</span> <span class="n">DiaOneClass₁.one_dia</span> <span class="n">c</span><span class="o">,</span> <span class="bp">←</span> <span class="n">hba</span><span class="o">,</span> <span class="n">Semigroup₁.dia_assoc</span><span class="o">,</span> <span class="n">hac</span><span class="o">,</span> <span class="n">DiaOneClass₁.dia_one</span> <span class="n">b</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">lemma</span><span class="w"> </span><span class="n">left_inv_eq_right_inv₁</span><span class="w"> </span><span class="o">{</span><span class="n">M</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid₁</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hba</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">⋄</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">𝟙</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hac</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">⋄</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">𝟙</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="bp">←</span><span class="w"> </span><span class="n">DiaOneClass₁.one_dia</span><span class="w"> </span><span class="n">c</span><span class="o">,</span><span class="w"> </span><span class="bp">←</span><span class="w"> </span><span class="n">hba</span><span class="o">,</span><span class="w"> </span><span class="n">Semigroup₁.dia_assoc</span><span class="o">,</span><span class="w"> </span><span class="n">hac</span><span class="o">,</span><span class="w"> </span><span class="n">DiaOneClass₁.dia_one</span><span class="w"> </span><span class="n">b</span><span class="o">]</span> </pre></div> </div> <p>In this lemma, it is pretty annoying to give full names, especially since it requires knowing which part of the hierarchy provides those facts. One way to fix this is to use the <code class="docutils literal notranslate"><span class="pre">export</span></code> command to copy those facts as lemmas in the root name space.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">export</span> <span class="n">DiaOneClass₁</span> <span class="o">(</span><span class="n">one_dia</span> <span class="n">dia_one</span><span class="o">)</span> <span class="kn">export</span> <span class="n">Semigroup₁</span> <span class="o">(</span><span class="n">dia_assoc</span><span class="o">)</span> <span class="kn">export</span> <span class="n">Group₁</span> <span class="o">(</span><span class="n">inv_dia</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">export</span><span class="w"> </span><span class="n">DiaOneClass₁</span><span class="w"> </span><span class="o">(</span><span class="n">one_dia</span><span class="w"> </span><span class="n">dia_one</span><span class="o">)</span> <span class="kn">export</span><span class="w"> </span><span class="n">Semigroup₁</span><span class="w"> </span><span class="o">(</span><span class="n">dia_assoc</span><span class="o">)</span> <span class="kn">export</span><span class="w"> </span><span class="n">Group₁</span><span class="w"> </span><span class="o">(</span><span class="n">inv_dia</span><span class="o">)</span> </pre></div> </div> <p>We can then rewrite the above proof as:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">M</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">}</span> <span class="o">[</span><span class="n">Monoid₁</span> <span class="n">M</span><span class="o">]</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">M</span><span class="o">}</span> <span class="o">(</span><span class="n">hba</span> <span class="o">:</span> <span class="n">b</span> <span class="bp">⋄</span> <span class="n">a</span> <span class="bp">=</span> <span class="mi">𝟙</span><span class="o">)</span> <span class="o">(</span><span class="n">hac</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">⋄</span> <span class="n">c</span> <span class="bp">=</span> <span class="mi">𝟙</span><span class="o">)</span> <span class="o">:</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">c</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="bp">←</span> <span class="n">one_dia</span> <span class="n">c</span><span class="o">,</span> <span class="bp">←</span> <span class="n">hba</span><span class="o">,</span> <span class="n">dia_assoc</span><span class="o">,</span> <span class="n">hac</span><span class="o">,</span> <span class="n">dia_one</span> <span class="n">b</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">M</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid₁</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hba</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">⋄</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">𝟙</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hac</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">⋄</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">𝟙</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="bp">←</span><span class="w"> </span><span class="n">one_dia</span><span class="w"> </span><span class="n">c</span><span class="o">,</span><span class="w"> </span><span class="bp">←</span><span class="w"> </span><span class="n">hba</span><span class="o">,</span><span class="w"> </span><span class="n">dia_assoc</span><span class="o">,</span><span class="w"> </span><span class="n">hac</span><span class="o">,</span><span class="w"> </span><span class="n">dia_one</span><span class="w"> </span><span class="n">b</span><span class="o">]</span> </pre></div> </div> <p>It is now your turn to prove things about our algebraic structures.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">lemma</span> <span class="n">inv_eq_of_dia</span> <span class="o">[</span><span class="n">Group₁</span> <span class="n">G</span><span class="o">]</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">G</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">⋄</span> <span class="n">b</span> <span class="bp">=</span> <span class="mi">𝟙</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span><span class="bp">⁻¹</span> <span class="bp">=</span> <span class="n">b</span> <span class="o">:=</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">lemma</span><span class="w"> </span><span class="n">inv_eq_of_dia</span><span class="w"> </span><span class="o">[</span><span class="n">Group₁</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">⋄</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">𝟙</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="bp">⁻¹</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">lemma</span> <span class="n">dia_inv</span> <span class="o">[</span><span class="n">Group₁</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">⋄</span> <span class="n">a</span><span class="bp">⁻¹</span> <span class="bp">=</span> <span class="mi">𝟙</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">lemma</span><span class="w"> </span><span class="n">dia_inv</span><span class="w"> </span><span class="o">[</span><span class="n">Group₁</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">⋄</span><span class="w"> </span><span class="n">a</span><span class="bp">⁻¹</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">𝟙</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>At this stage we would like to move on to define rings, but there is a serious issue.
-
@@ -329,84 +330,84 @@ lemmas are then only stated in multiplicative notation and marked with the attribute <code class="docutils literal notranslate"><span class="pre">to_additive</span></code>to generate the additive version as <code class="docutils literal notranslate"><span class="pre">left_inv_eq_right_inv'</span></code> with its auto-generated additive version <code class="docutils literal notranslate"><span class="pre">left_neg_eq_right_neg'</span></code>. In order to check the name of this additive version we used the <code class="docutils literal notranslate"><span class="pre">whatsnew</span> <span class="pre">in</span></code> command on top of <code class="docutils literal notranslate"><span class="pre">left_inv_eq_right_inv'</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span> <span class="n">AddSemigroup₃</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="kd">extends</span> <span class="n">Add</span> <span class="n">α</span> <span class="n">where</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span><span class="w"> </span><span class="n">AddSemigroup₃</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="kd">extends</span><span class="w"> </span><span class="n">Add</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="n">where</span> <span class="sd">/-- Addition is associative -/</span> <span class="n">add_assoc₃</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">α</span><span class="o">,</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">+</span> <span class="n">c</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">+</span> <span class="o">(</span><span class="n">b</span> <span class="bp">+</span> <span class="n">c</span><span class="o">)</span> <span class="w"> </span><span class="n">add_assoc₃</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="o">)</span> <span class="kd">@[</span><span class="n">to_additive</span> <span class="n">AddSemigroup₃</span><span class="kd">]</span> <span class="kd">class</span> <span class="n">Semigroup₃</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="kd">extends</span> <span class="n">Mul</span> <span class="n">α</span> <span class="n">where</span> <span class="kd">@[</span><span class="n">to_additive</span><span class="w"> </span><span class="n">AddSemigroup₃</span><span class="kd">]</span> <span class="kd">class</span><span class="w"> </span><span class="n">Semigroup₃</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="kd">extends</span><span class="w"> </span><span class="n">Mul</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="n">where</span> <span class="sd">/-- Multiplication is associative -/</span> <span class="n">mul_assoc₃</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">α</span><span class="o">,</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">c</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="o">(</span><span class="n">b</span> <span class="bp">*</span> <span class="n">c</span><span class="o">)</span> <span class="w"> </span><span class="n">mul_assoc₃</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="o">)</span> <span class="kd">class</span> <span class="n">AddMonoid₃</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="kd">extends</span> <span class="n">AddSemigroup₃</span> <span class="n">α</span><span class="o">,</span> <span class="n">AddZeroClass</span> <span class="n">α</span> <span class="kd">class</span><span class="w"> </span><span class="n">AddMonoid₃</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="kd">extends</span><span class="w"> </span><span class="n">AddSemigroup₃</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">AddZeroClass</span><span class="w"> </span><span class="n">α</span> <span class="kd">@[</span><span class="n">to_additive</span> <span class="n">AddMonoid₃</span><span class="kd">]</span> <span class="kd">class</span> <span class="n">Monoid₃</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="kd">extends</span> <span class="n">Semigroup₃</span> <span class="n">α</span><span class="o">,</span> <span class="n">MulOneClass</span> <span class="n">α</span> <span class="kd">@[</span><span class="n">to_additive</span><span class="w"> </span><span class="n">AddMonoid₃</span><span class="kd">]</span> <span class="kd">class</span><span class="w"> </span><span class="n">Monoid₃</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="kd">extends</span><span class="w"> </span><span class="n">Semigroup₃</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">MulOneClass</span><span class="w"> </span><span class="n">α</span> <span class="kn">attribute</span> <span class="o">[</span><span class="n">to_additive</span> <span class="n">existing</span><span class="o">]</span> <span class="n">Monoid₃.toMulOneClass</span> <span class="kn">attribute</span><span class="w"> </span><span class="o">[</span><span class="n">to_additive</span><span class="w"> </span><span class="n">existing</span><span class="o">]</span><span class="w"> </span><span class="n">Monoid₃.toMulOneClass</span> <span class="kn">export</span> <span class="n">Semigroup₃</span> <span class="o">(</span><span class="n">mul_assoc₃</span><span class="o">)</span> <span class="kn">export</span> <span class="n">AddSemigroup₃</span> <span class="o">(</span><span class="n">add_assoc₃</span><span class="o">)</span> <span class="kn">export</span><span class="w"> </span><span class="n">Semigroup₃</span><span class="w"> </span><span class="o">(</span><span class="n">mul_assoc₃</span><span class="o">)</span> <span class="kn">export</span><span class="w"> </span><span class="n">AddSemigroup₃</span><span class="w"> </span><span class="o">(</span><span class="n">add_assoc₃</span><span class="o">)</span> <span class="n">whatsnew</span> <span class="k">in</span> <span class="n">whatsnew</span><span class="w"> </span><span class="k">in</span> <span class="kd">@[</span><span class="n">to_additive</span><span class="kd">]</span> <span class="kd">lemma</span> <span class="n">left_inv_eq_right_inv'</span> <span class="o">{</span><span class="n">M</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">}</span> <span class="o">[</span><span class="n">Monoid₃</span> <span class="n">M</span><span class="o">]</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">M</span><span class="o">}</span> <span class="o">(</span><span class="n">hba</span> <span class="o">:</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">=</span> <span class="mi">1</span><span class="o">)</span> <span class="o">(</span><span class="n">hac</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">c</span> <span class="bp">=</span> <span class="mi">1</span><span class="o">)</span> <span class="o">:</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">c</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="bp">←</span> <span class="n">one_mul</span> <span class="n">c</span><span class="o">,</span> <span class="bp">←</span> <span class="n">hba</span><span class="o">,</span> <span class="n">mul_assoc₃</span><span class="o">,</span> <span class="n">hac</span><span class="o">,</span> <span class="n">mul_one</span> <span class="n">b</span><span class="o">]</span> <span class="kd">lemma</span><span class="w"> </span><span class="n">left_inv_eq_right_inv'</span><span class="w"> </span><span class="o">{</span><span class="n">M</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid₃</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hba</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hac</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="bp">←</span><span class="w"> </span><span class="n">one_mul</span><span class="w"> </span><span class="n">c</span><span class="o">,</span><span class="w"> </span><span class="bp">←</span><span class="w"> </span><span class="n">hba</span><span class="o">,</span><span class="w"> </span><span class="n">mul_assoc₃</span><span class="o">,</span><span class="w"> </span><span class="n">hac</span><span class="o">,</span><span class="w"> </span><span class="n">mul_one</span><span class="w"> </span><span class="n">b</span><span class="o">]</span> <span class="k">#check</span> <span class="n">left_neg_eq_right_neg'</span> <span class="k">#check</span><span class="w"> </span><span class="n">left_neg_eq_right_neg'</span> </pre></div> </div> <p>Equipped with this technology, we can easily define also commutative semigroups, monoids and groups, and then define rings.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span> <span class="n">AddCommSemigroup₃</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="kd">extends</span> <span class="n">AddSemigroup₃</span> <span class="n">α</span> <span class="n">where</span> <span class="n">add_comm</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">α</span><span class="o">,</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">b</span> <span class="bp">+</span> <span class="n">a</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span><span class="w"> </span><span class="n">AddCommSemigroup₃</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="kd">extends</span><span class="w"> </span><span class="n">AddSemigroup₃</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">add_comm</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">a</span> <span class="kd">@[</span><span class="n">to_additive</span> <span class="n">AddCommSemigroup₃</span><span class="kd">]</span> <span class="kd">class</span> <span class="n">CommSemigroup₃</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="kd">extends</span> <span class="n">Semigroup₃</span> <span class="n">α</span> <span class="n">where</span> <span class="n">mul_comm</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">α</span><span class="o">,</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">a</span> <span class="kd">@[</span><span class="n">to_additive</span><span class="w"> </span><span class="n">AddCommSemigroup₃</span><span class="kd">]</span> <span class="kd">class</span><span class="w"> </span><span class="n">CommSemigroup₃</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="kd">extends</span><span class="w"> </span><span class="n">Semigroup₃</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">mul_comm</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span> <span class="kd">class</span> <span class="n">AddCommMonoid₃</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="kd">extends</span> <span class="n">AddMonoid₃</span> <span class="n">α</span><span class="o">,</span> <span class="n">AddCommSemigroup₃</span> <span class="n">α</span> <span class="kd">class</span><span class="w"> </span><span class="n">AddCommMonoid₃</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="kd">extends</span><span class="w"> </span><span class="n">AddMonoid₃</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">AddCommSemigroup₃</span><span class="w"> </span><span class="n">α</span> <span class="kd">@[</span><span class="n">to_additive</span> <span class="n">AddCommMonoid₃</span><span class="kd">]</span> <span class="kd">class</span> <span class="n">CommMonoid₃</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="kd">extends</span> <span class="n">Monoid₃</span> <span class="n">α</span><span class="o">,</span> <span class="n">CommSemigroup₃</span> <span class="n">α</span> <span class="kd">@[</span><span class="n">to_additive</span><span class="w"> </span><span class="n">AddCommMonoid₃</span><span class="kd">]</span> <span class="kd">class</span><span class="w"> </span><span class="n">CommMonoid₃</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="kd">extends</span><span class="w"> </span><span class="n">Monoid₃</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="n">CommSemigroup₃</span><span class="w"> </span><span class="n">α</span> <span class="kd">class</span> <span class="n">AddGroup₃</span> <span class="o">(</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="kd">extends</span> <span class="n">AddMonoid₃</span> <span class="n">G</span><span class="o">,</span> <span class="n">Neg</span> <span class="n">G</span> <span class="n">where</span> <span class="n">neg_add</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="o">:</span> <span class="n">G</span><span class="o">,</span> <span class="bp">-</span><span class="n">a</span> <span class="bp">+</span> <span class="n">a</span> <span class="bp">=</span> <span class="mi">0</span> <span class="kd">class</span><span class="w"> </span><span class="n">AddGroup₃</span><span class="w"> </span><span class="o">(</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="kd">extends</span><span class="w"> </span><span class="n">AddMonoid₃</span><span class="w"> </span><span class="n">G</span><span class="o">,</span><span class="w"> </span><span class="n">Neg</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">neg_add</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">,</span><span class="w"> </span><span class="bp">-</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span> <span class="kd">@[</span><span class="n">to_additive</span> <span class="n">AddGroup₃</span><span class="kd">]</span> <span class="kd">class</span> <span class="n">Group₃</span> <span class="o">(</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="kd">extends</span> <span class="n">Monoid₃</span> <span class="n">G</span><span class="o">,</span> <span class="n">Inv</span> <span class="n">G</span> <span class="n">where</span> <span class="n">inv_mul</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="o">:</span> <span class="n">G</span><span class="o">,</span> <span class="n">a</span><span class="bp">⁻¹</span> <span class="bp">*</span> <span class="n">a</span> <span class="bp">=</span> <span class="mi">1</span> <span class="kd">@[</span><span class="n">to_additive</span><span class="w"> </span><span class="n">AddGroup₃</span><span class="kd">]</span> <span class="kd">class</span><span class="w"> </span><span class="n">Group₃</span><span class="w"> </span><span class="o">(</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="kd">extends</span><span class="w"> </span><span class="n">Monoid₃</span><span class="w"> </span><span class="n">G</span><span class="o">,</span><span class="w"> </span><span class="n">Inv</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">inv_mul</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="bp">⁻¹</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span> </pre></div> </div> <p>We should remember to tag lemmas with <code class="docutils literal notranslate"><span class="pre">simp</span></code> when appropriate.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">attribute</span> <span class="o">[</span><span class="n">simp</span><span class="o">]</span> <span class="n">Group₃.inv_mul</span> <span class="n">AddGroup₃.neg_add</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">attribute</span><span class="w"> </span><span class="o">[</span><span class="n">simp</span><span class="o">]</span><span class="w"> </span><span class="n">Group₃.inv_mul</span><span class="w"> </span><span class="n">AddGroup₃.neg_add</span> </pre></div> </div> <p>Then we need to repeat ourselves a bit since we switch to standard notations, but at least <code class="docutils literal notranslate"><span class="pre">to_additive</span></code> does the work of translating from the multiplicative notation to the additive one.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">@[</span><span class="n">to_additive</span><span class="kd">]</span> <span class="kd">lemma</span> <span class="n">inv_eq_of_mul</span> <span class="o">[</span><span class="n">Group₃</span> <span class="n">G</span><span class="o">]</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">G</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">=</span> <span class="mi">1</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span><span class="bp">⁻¹</span> <span class="bp">=</span> <span class="n">b</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">lemma</span><span class="w"> </span><span class="n">inv_eq_of_mul</span><span class="w"> </span><span class="o">[</span><span class="n">Group₃</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="bp">⁻¹</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Note that <code class="docutils literal notranslate"><span class="pre">to_additive</span></code> can be asked to tag a lemma with <code class="docutils literal notranslate"><span class="pre">simp</span></code> and propagate that attribute to the additive version as follows.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">@[</span><span class="n">to_additive</span> <span class="o">(</span><span class="n">attr</span> <span class="o">:=</span> <span class="n">simp</span><span class="o">)</span><span class="kd">]</span> <span class="kd">lemma</span> <span class="n">Group₃.mul_inv</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">}</span> <span class="o">[</span><span class="n">Group₃</span> <span class="n">G</span><span class="o">]</span> <span class="o">{</span><span class="n">a</span> <span class="o">:</span> <span class="n">G</span><span class="o">}</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">a</span><span class="bp">⁻¹</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">@[</span><span class="n">to_additive</span><span class="w"> </span><span class="o">(</span><span class="n">attr</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">simp</span><span class="o">)</span><span class="kd">]</span> <span class="kd">lemma</span><span class="w"> </span><span class="n">Group₃.mul_inv</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group₃</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">a</span><span class="bp">⁻¹</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">@[</span><span class="n">to_additive</span><span class="kd">]</span> <span class="kd">lemma</span> <span class="n">mul_left_cancel₃</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">}</span> <span class="o">[</span><span class="n">Group₃</span> <span class="n">G</span><span class="o">]</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">G</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">c</span><span class="o">)</span> <span class="o">:</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">c</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">lemma</span><span class="w"> </span><span class="n">mul_left_cancel₃</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group₃</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">@[</span><span class="n">to_additive</span><span class="kd">]</span> <span class="kd">lemma</span> <span class="n">mul_right_cancel₃</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">}</span> <span class="o">[</span><span class="n">Group₃</span> <span class="n">G</span><span class="o">]</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">G</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">b</span><span class="bp">*</span><span class="n">a</span> <span class="bp">=</span> <span class="n">c</span><span class="bp">*</span><span class="n">a</span><span class="o">)</span> <span class="o">:</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">c</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">lemma</span><span class="w"> </span><span class="n">mul_right_cancel₃</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group₃</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="bp">*</span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">c</span><span class="bp">*</span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">class</span> <span class="n">AddCommGroup₃</span> <span class="o">(</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="kd">extends</span> <span class="n">AddGroup₃</span> <span class="n">G</span><span class="o">,</span> <span class="n">AddCommMonoid₃</span> <span class="n">G</span> <span class="kd">class</span><span class="w"> </span><span class="n">AddCommGroup₃</span><span class="w"> </span><span class="o">(</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="kd">extends</span><span class="w"> </span><span class="n">AddGroup₃</span><span class="w"> </span><span class="n">G</span><span class="o">,</span><span class="w"> </span><span class="n">AddCommMonoid₃</span><span class="w"> </span><span class="n">G</span> <span class="kd">@[</span><span class="n">to_additive</span> <span class="n">AddCommGroup₃</span><span class="kd">]</span> <span class="kd">class</span> <span class="n">CommGroup₃</span> <span class="o">(</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="kd">extends</span> <span class="n">Group₃</span> <span class="n">G</span><span class="o">,</span> <span class="n">CommMonoid₃</span> <span class="n">G</span> <span class="kd">@[</span><span class="n">to_additive</span><span class="w"> </span><span class="n">AddCommGroup₃</span><span class="kd">]</span> <span class="kd">class</span><span class="w"> </span><span class="n">CommGroup₃</span><span class="w"> </span><span class="o">(</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="kd">extends</span><span class="w"> </span><span class="n">Group₃</span><span class="w"> </span><span class="n">G</span><span class="o">,</span><span class="w"> </span><span class="n">CommMonoid₃</span><span class="w"> </span><span class="n">G</span> </pre></div> </div> <p>We are now ready for rings. For demonstration purposes we won’t assume that addition is
-
@@ -416,56 +417,56 @@ also because Mathlib’s algebraic hierarchy goes through semirings which are like rings but withoutopposites so that the proof below does not work for them. What we gain here, besides a nice exercise if you have never seen it, is an example of building an instance using the syntax that allows to provide a parent structure and some extra fields.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span> <span class="n">Ring₃</span> <span class="o">(</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="kd">extends</span> <span class="n">AddGroup₃</span> <span class="n">R</span><span class="o">,</span> <span class="n">Monoid₃</span> <span class="n">R</span><span class="o">,</span> <span class="n">MulZeroClass</span> <span class="n">R</span> <span class="n">where</span> <span class="sd">/-- Multiplication is left distributive over addition -/</span> <span class="n">left_distrib</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">R</span><span class="o">,</span> <span class="n">a</span> <span class="bp">*</span> <span class="o">(</span><span class="n">b</span> <span class="bp">+</span> <span class="n">c</span><span class="o">)</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">+</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">c</span> <span class="sd">/-- Multiplication is right distributive over addition -/</span> <span class="n">right_distrib</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">R</span><span class="o">,</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">*</span> <span class="n">c</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">c</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">*</span> <span class="n">c</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span><span class="w"> </span><span class="n">Ring₃</span><span class="w"> </span><span class="o">(</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="kd">extends</span><span class="w"> </span><span class="n">AddGroup₃</span><span class="w"> </span><span class="n">R</span><span class="o">,</span><span class="w"> </span><span class="n">Monoid₃</span><span class="w"> </span><span class="n">R</span><span class="o">,</span><span class="w"> </span><span class="n">MulZeroClass</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="sd">/-- Multiplication is left distributive over addition -/</span> <span class="w"> </span><span class="n">left_distrib</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">c</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span> <span class="w"> </span><span class="sd">/-- Multiplication is right distributive over addition -/</span> <span class="w"> </span><span class="n">right_distrib</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">,</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span> <span class="kd">instance</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">}</span> <span class="o">[</span><span class="n">Ring₃</span> <span class="n">R</span><span class="o">]</span> <span class="o">:</span> <span class="n">AddCommGroup₃</span> <span class="n">R</span> <span class="o">:=</span> <span class="o">{</span> <span class="n">Ring₃.toAddGroup₃</span> <span class="k">with</span> <span class="n">add_comm</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="o">}</span> <span class="kd">instance</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Ring₃</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">AddCommGroup₃</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="o">:=</span> <span class="o">{</span><span class="w"> </span><span class="n">Ring₃.toAddGroup₃</span><span class="w"> </span><span class="k">with</span> <span class="w"> </span><span class="n">add_comm</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span><span class="w"> </span><span class="o">}</span> </pre></div> </div> <p>Of course we can also build concrete instances, such as a ring structure on integers (of course the instance below uses that all the work is already done in Mathlib).</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span> <span class="o">:</span> <span class="n">Ring₃</span> <span class="n">ℤ</span> <span class="n">where</span> <span class="n">add</span> <span class="o">:=</span> <span class="o">(</span><span class="bp">·</span> <span class="bp">+</span> <span class="bp">·</span><span class="o">)</span> <span class="n">add_assoc₃</span> <span class="o">:=</span> <span class="n">add_assoc</span> <span class="n">zero</span> <span class="o">:=</span> <span class="mi">0</span> <span class="n">zero_add</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="n">add_zero</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="n">neg</span> <span class="o">:=</span> <span class="o">(</span><span class="bp">-</span> <span class="bp">·</span><span class="o">)</span> <span class="n">neg_add</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="n">mul</span> <span class="o">:=</span> <span class="o">(</span><span class="bp">·</span> <span class="bp">*</span> <span class="bp">·</span><span class="o">)</span> <span class="n">mul_assoc₃</span> <span class="o">:=</span> <span class="n">mul_assoc</span> <span class="n">one</span> <span class="o">:=</span> <span class="mi">1</span> <span class="n">one_mul</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="n">mul_one</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="n">zero_mul</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="n">mul_zero</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="n">left_distrib</span> <span class="o">:=</span> <span class="n">Int.mul_add</span> <span class="n">right_distrib</span> <span class="o">:=</span> <span class="n">Int.add_mul</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Ring₃</span><span class="w"> </span><span class="n">ℤ</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="bp">·</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="bp">·</span><span class="o">)</span> <span class="w"> </span><span class="n">add_assoc₃</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">add_assoc</span> <span class="w"> </span><span class="n">zero</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">0</span> <span class="w"> </span><span class="n">zero_add</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="n">add_zero</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="n">neg</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="bp">-</span><span class="w"> </span><span class="bp">·</span><span class="o">)</span> <span class="w"> </span><span class="n">neg_add</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="bp">·</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="bp">·</span><span class="o">)</span> <span class="w"> </span><span class="n">mul_assoc₃</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">mul_assoc</span> <span class="w"> </span><span class="n">one</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">1</span> <span class="w"> </span><span class="n">one_mul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="n">mul_one</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="n">zero_mul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="n">mul_zero</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="n">left_distrib</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Int.mul_add</span> <span class="w"> </span><span class="n">right_distrib</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Int.add_mul</span> </pre></div> </div> <p>As an exercise you can now set up a simple hierarchy for order relations, including a class for ordered commutative monoids, which have both a partial order and a commutative monoid structure such that <code class="docutils literal notranslate"><span class="pre">∀</span> <span class="pre">a</span> <span class="pre">b</span> <span class="pre">:</span> <span class="pre">α,</span> <span class="pre">a</span> <span class="pre">≤</span> <span class="pre">b</span> <span class="pre">→</span> <span class="pre">∀</span> <span class="pre">c</span> <span class="pre">:</span> <span class="pre">α,</span> <span class="pre">c</span> <span class="pre">*</span> <span class="pre">a</span> <span class="pre">≤</span> <span class="pre">c</span> <span class="pre">*</span> <span class="pre">b</span></code>. Of course you need to add fields and maybe <code class="docutils literal notranslate"><span class="pre">extends</span></code> clauses to the following classes.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span> <span class="n">LE₁</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="n">where</span> <span class="sd">/-- The Less-or-Equal relation. -/</span> <span class="n">le</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">α</span> <span class="bp">→</span> <span class="kt">Prop</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span><span class="w"> </span><span class="n">LE₁</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="sd">/-- The Less-or-Equal relation. -/</span> <span class="w"> </span><span class="n">le</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="kt">Prop</span> <span class="kd">@[</span><span class="n">inherit_doc</span><span class="kd">]</span> <span class="kd">infix</span><span class="o">:</span><span class="mi">50</span> <span class="s2">" ≤₁ "</span> <span class="bp">=></span> <span class="n">LE₁.le</span> <span class="kd">@[</span><span class="n">inherit_doc</span><span class="kd">]</span><span class="w"> </span><span class="kd">infix</span><span class="o">:</span><span class="mi">50</span><span class="w"> </span><span class="s2">" ≤₁ "</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="n">LE₁.le</span> <span class="kd">class</span> <span class="n">Preorder₁</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="kd">class</span><span class="w"> </span><span class="n">Preorder₁</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span> <span class="kd">class</span> <span class="n">PartialOrder₁</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="kd">class</span><span class="w"> </span><span class="n">PartialOrder₁</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span> <span class="kd">class</span> <span class="n">OrderedCommMonoid₁</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="kd">class</span><span class="w"> </span><span class="n">OrderedCommMonoid₁</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span> <span class="kd">instance</span> <span class="o">:</span> <span class="n">OrderedCommMonoid₁</span> <span class="n">ℕ</span> <span class="n">where</span> <span class="kd">instance</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">OrderedCommMonoid₁</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="n">where</span> </pre></div> </div> <p>We now want to discuss algebraic structures involving several types. The prime example
-
@@ -474,20 +475,20 @@ and think that all our rings are fields. Those structures are commutative additive groupsequipped with a scalar multiplication by elements of some ring.</p> <p>We first define the data-carrying type class of scalar multiplication by some type <code class="docutils literal notranslate"><span class="pre">α</span></code> on some type <code class="docutils literal notranslate"><span class="pre">β</span></code>, and give it a right associative notation.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span> <span class="n">SMul₃</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">(</span><span class="n">β</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="n">where</span> <span class="sd">/-- Scalar multiplication -/</span> <span class="n">smul</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">β</span> <span class="bp">→</span> <span class="n">β</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span><span class="w"> </span><span class="n">SMul₃</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">β</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="sd">/-- Scalar multiplication -/</span> <span class="w"> </span><span class="n">smul</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">β</span> <span class="kd">infixr</span><span class="o">:</span><span class="mi">73</span> <span class="s2">" • "</span> <span class="bp">=></span> <span class="n">SMul₃.smul</span> <span class="kd">infixr</span><span class="o">:</span><span class="mi">73</span><span class="w"> </span><span class="s2">" • "</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="n">SMul₃.smul</span> </pre></div> </div> <p>Then we can define modules (again think about vector spaces if you don’t know what is a module).</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span> <span class="n">Module₁</span> <span class="o">(</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">Ring₃</span> <span class="n">R</span><span class="o">]</span> <span class="o">(</span><span class="n">M</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">AddCommGroup₃</span> <span class="n">M</span><span class="o">]</span> <span class="kd">extends</span> <span class="n">SMul₃</span> <span class="n">R</span> <span class="n">M</span> <span class="n">where</span> <span class="n">zero_smul</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">m</span> <span class="o">:</span> <span class="n">M</span><span class="o">,</span> <span class="o">(</span><span class="mi">0</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="bp">•</span> <span class="n">m</span> <span class="bp">=</span> <span class="mi">0</span> <span class="n">one_smul</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">m</span> <span class="o">:</span> <span class="n">M</span><span class="o">,</span> <span class="o">(</span><span class="mi">1</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="bp">•</span> <span class="n">m</span> <span class="bp">=</span> <span class="n">m</span> <span class="n">mul_smul</span> <span class="o">:</span> <span class="bp">∀</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">(</span><span class="n">m</span> <span class="o">:</span> <span class="n">M</span><span class="o">),</span> <span class="o">(</span><span class="n">a</span> <span class="bp">*</span> <span class="n">b</span><span class="o">)</span> <span class="bp">•</span> <span class="n">m</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">•</span> <span class="n">b</span> <span class="bp">•</span> <span class="n">m</span> <span class="n">add_smul</span> <span class="o">:</span> <span class="bp">∀</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">(</span><span class="n">m</span> <span class="o">:</span> <span class="n">M</span><span class="o">),</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">•</span> <span class="n">m</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">•</span> <span class="n">m</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">•</span> <span class="n">m</span> <span class="n">smul_add</span> <span class="o">:</span> <span class="bp">∀</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">(</span><span class="n">m</span> <span class="n">n</span> <span class="o">:</span> <span class="n">M</span><span class="o">),</span> <span class="n">a</span> <span class="bp">•</span> <span class="o">(</span><span class="n">m</span> <span class="bp">+</span> <span class="n">n</span><span class="o">)</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">•</span> <span class="n">m</span> <span class="bp">+</span> <span class="n">a</span> <span class="bp">•</span> <span class="n">n</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span><span class="w"> </span><span class="n">Module₁</span><span class="w"> </span><span class="o">(</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">Ring₃</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">M</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">AddCommGroup₃</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="kd">extends</span><span class="w"> </span><span class="n">SMul₃</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">zero_smul</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="o">,</span><span class="w"> </span><span class="o">(</span><span class="mi">0</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span> <span class="w"> </span><span class="n">one_smul</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="o">,</span><span class="w"> </span><span class="o">(</span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">m</span> <span class="w"> </span><span class="n">mul_smul</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="o">),</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">m</span> <span class="w"> </span><span class="n">add_smul</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="o">),</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">m</span> <span class="w"> </span><span class="n">smul_add</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="o">),</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">n</span> </pre></div> </div> <p>There is something interesting going on here. While it isn’t too surprising that the
-
@@ -514,13 +515,13 @@ safely be used as an instance. The rule is easy to remember: each class appearing in the<code class="docutils literal notranslate"><span class="pre">extends</span></code> clause should mention every type appearing in the parameters.</p> <p>Let us create our first module instance: a ring is a module over itself using its multiplication as a scalar multiplication.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span> <span class="n">selfModule</span> <span class="o">(</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">Ring₃</span> <span class="n">R</span><span class="o">]</span> <span class="o">:</span> <span class="n">Module₁</span> <span class="n">R</span> <span class="n">R</span> <span class="n">where</span> <span class="n">smul</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">r</span> <span class="n">s</span> <span class="bp">↦</span> <span class="n">r</span><span class="bp">*</span><span class="n">s</span> <span class="n">zero_smul</span> <span class="o">:=</span> <span class="n">zero_mul</span> <span class="n">one_smul</span> <span class="o">:=</span> <span class="n">one_mul</span> <span class="n">mul_smul</span> <span class="o">:=</span> <span class="n">mul_assoc₃</span> <span class="n">add_smul</span> <span class="o">:=</span> <span class="n">Ring₃.right_distrib</span> <span class="n">smul_add</span> <span class="o">:=</span> <span class="n">Ring₃.left_distrib</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span><span class="w"> </span><span class="n">selfModule</span><span class="w"> </span><span class="o">(</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">Ring₃</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Module₁</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">smul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">r</span><span class="bp">*</span><span class="n">s</span> <span class="w"> </span><span class="n">zero_smul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">zero_mul</span> <span class="w"> </span><span class="n">one_smul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">one_mul</span> <span class="w"> </span><span class="n">mul_smul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">mul_assoc₃</span> <span class="w"> </span><span class="n">add_smul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Ring₃.right_distrib</span> <span class="w"> </span><span class="n">smul_add</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Ring₃.left_distrib</span> </pre></div> </div> <p>As a second example, every abelian group is a module over <code class="docutils literal notranslate"><span class="pre">ℤ</span></code> (this is one of the reason to
-
@@ -528,26 +529,26 @@ generalize the theory of vector spaces by allowing non-invertible scalars). First one can definescalar multiplication by a natural number for any type equipped with a zero and an addition: <code class="docutils literal notranslate"><span class="pre">n</span> <span class="pre">•</span> <span class="pre">a</span></code> is defined as <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">+</span> <span class="pre">⋯</span> <span class="pre">+</span> <span class="pre">a</span></code> where <code class="docutils literal notranslate"><span class="pre">a</span></code> appears <code class="docutils literal notranslate"><span class="pre">n</span></code> times. Then this is extended to scalar multiplication by an integer by ensuring <code class="docutils literal notranslate"><span class="pre">(-1)</span> <span class="pre">•</span> <span class="pre">a</span> <span class="pre">=</span> <span class="pre">-a</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">nsmul₁</span> <span class="o">[</span><span class="n">Zero</span> <span class="n">M</span><span class="o">]</span> <span class="o">[</span><span class="n">Add</span> <span class="n">M</span><span class="o">]</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">M</span> <span class="bp">→</span> <span class="n">M</span> <span class="bp">|</span> <span class="mi">0</span><span class="o">,</span> <span class="n">_</span> <span class="bp">=></span> <span class="mi">0</span> <span class="bp">|</span> <span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">,</span> <span class="n">a</span> <span class="bp">=></span> <span class="n">a</span> <span class="bp">+</span> <span class="n">nsmul₁</span> <span class="n">n</span> <span class="n">a</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">nsmul₁</span><span class="w"> </span><span class="o">[</span><span class="n">Zero</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Add</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">M</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="mi">0</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">nsmul₁</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">a</span> <span class="kd">def</span> <span class="n">zsmul₁</span> <span class="o">{</span><span class="n">M</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Zero</span> <span class="n">M</span><span class="o">]</span> <span class="o">[</span><span class="n">Add</span> <span class="n">M</span><span class="o">]</span> <span class="o">[</span><span class="n">Neg</span> <span class="n">M</span><span class="o">]</span> <span class="o">:</span> <span class="n">ℤ</span> <span class="bp">→</span> <span class="n">M</span> <span class="bp">→</span> <span class="n">M</span> <span class="bp">|</span> <span class="n">Int.ofNat</span> <span class="n">n</span><span class="o">,</span> <span class="n">a</span> <span class="bp">=></span> <span class="n">nsmul₁</span> <span class="n">n</span> <span class="n">a</span> <span class="bp">|</span> <span class="n">Int.negSucc</span> <span class="n">n</span><span class="o">,</span> <span class="n">a</span> <span class="bp">=></span> <span class="bp">-</span><span class="n">nsmul₁</span> <span class="n">n.succ</span> <span class="n">a</span> <span class="kd">def</span><span class="w"> </span><span class="n">zsmul₁</span><span class="w"> </span><span class="o">{</span><span class="n">M</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Zero</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Add</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Neg</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℤ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">M</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">Int.ofNat</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="n">nsmul₁</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">a</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">Int.negSucc</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="bp">-</span><span class="n">nsmul₁</span><span class="w"> </span><span class="n">n.succ</span><span class="w"> </span><span class="n">a</span> </pre></div> </div> <p>Proving this gives rise to a module structure is a bit tedious and not interesting for the current discussion, so we will sorry all axioms. You are <em>not</em> asked to replace those sorries with proofs. If you insist on doing it then you will probably want to state and prove several intermediate lemmas about <code class="docutils literal notranslate"><span class="pre">nsmul₁</span></code> and <code class="docutils literal notranslate"><span class="pre">zsmul₁</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span> <span class="n">abGrpModule</span> <span class="o">(</span><span class="n">A</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">AddCommGroup₃</span> <span class="n">A</span><span class="o">]</span> <span class="o">:</span> <span class="n">Module₁</span> <span class="n">ℤ</span> <span class="n">A</span> <span class="n">where</span> <span class="n">smul</span> <span class="o">:=</span> <span class="n">zsmul₁</span> <span class="n">zero_smul</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">one_smul</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">mul_smul</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">add_smul</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">smul_add</span> <span class="o">:=</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span><span class="w"> </span><span class="n">abGrpModule</span><span class="w"> </span><span class="o">(</span><span class="n">A</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">AddCommGroup₃</span><span class="w"> </span><span class="n">A</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Module₁</span><span class="w"> </span><span class="n">ℤ</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">smul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">zsmul₁</span> <span class="w"> </span><span class="n">zero_smul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">one_smul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">mul_smul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">add_smul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">smul_add</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>A much more important issue is that we now have two module structures over the ring <code class="docutils literal notranslate"><span class="pre">ℤ</span></code>
-
@@ -558,7 +559,7 @@ this isn’t true by definition, it requires a proof. This is very bad news for the type classinstance resolution procedure and will lead to very frustrating failures for users of this hierarchy. When directly asked to find an instance, Lean will pick one, and we can see which one using:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="bp">#</span><span class="n">synth</span> <span class="n">Module₁</span> <span class="n">ℤ</span> <span class="n">ℤ</span> <span class="c1">-- abGrpModule ℤ</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="bp">#</span><span class="n">synth</span><span class="w"> </span><span class="n">Module₁</span><span class="w"> </span><span class="n">ℤ</span><span class="w"> </span><span class="n">ℤ</span><span class="w"> </span><span class="c1">-- abGrpModule ℤ</span> </pre></div> </div> <p>But in a more indirect context it can happen that Lean infers the other one and then gets confused.
-
@@ -582,46 +583,46 @@ field and some <code class="docutils literal notranslate"><span class="pre">Prop</span></code>-valued fields ensuring this operation is provably the one we constructedabove. Those fields are given default values using <code class="docutils literal notranslate"><span class="pre">:=</span></code> after their type in the definition below. Thanks to these default values, most instances would be constructed exactly as with our previous definitions. But in the special case of <code class="docutils literal notranslate"><span class="pre">ℤ</span></code> we will be able to provide specific values.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span> <span class="n">AddMonoid₄</span> <span class="o">(</span><span class="n">M</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="kd">extends</span> <span class="n">AddSemigroup₃</span> <span class="n">M</span><span class="o">,</span> <span class="n">AddZeroClass</span> <span class="n">M</span> <span class="n">where</span> <span class="sd">/-- Multiplication by a natural number. -/</span> <span class="n">nsmul</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">M</span> <span class="bp">→</span> <span class="n">M</span> <span class="o">:=</span> <span class="n">nsmul₁</span> <span class="sd">/-- Multiplication by `(0 : ℕ)` gives `0`. -/</span> <span class="n">nsmul_zero</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span><span class="o">,</span> <span class="n">nsmul</span> <span class="mi">0</span> <span class="n">x</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intros</span><span class="bp">;</span> <span class="n">rfl</span> <span class="sd">/-- Multiplication by `(n + 1 : ℕ)` behaves as expected. -/</span> <span class="n">nsmul_succ</span> <span class="o">:</span> <span class="bp">∀</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">x</span><span class="o">),</span> <span class="n">nsmul</span> <span class="o">(</span><span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">)</span> <span class="n">x</span> <span class="bp">=</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">nsmul</span> <span class="n">n</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intros</span><span class="bp">;</span> <span class="n">rfl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span><span class="w"> </span><span class="n">AddMonoid₄</span><span class="w"> </span><span class="o">(</span><span class="n">M</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="kd">extends</span><span class="w"> </span><span class="n">AddSemigroup₃</span><span class="w"> </span><span class="n">M</span><span class="o">,</span><span class="w"> </span><span class="n">AddZeroClass</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="sd">/-- Multiplication by a natural number. -/</span> <span class="w"> </span><span class="n">nsmul</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">nsmul₁</span> <span class="w"> </span><span class="sd">/-- Multiplication by `(0 : ℕ)` gives `0`. -/</span> <span class="w"> </span><span class="n">nsmul_zero</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">nsmul</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">intros</span><span class="bp">;</span><span class="w"> </span><span class="n">rfl</span> <span class="w"> </span><span class="sd">/-- Multiplication by `(n + 1 : ℕ)` behaves as expected. -/</span> <span class="w"> </span><span class="n">nsmul_succ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="o">),</span><span class="w"> </span><span class="n">nsmul</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">nsmul</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">intros</span><span class="bp">;</span><span class="w"> </span><span class="n">rfl</span> <span class="kd">instance</span> <span class="n">mySMul</span> <span class="o">{</span><span class="n">M</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">}</span> <span class="o">[</span><span class="n">AddMonoid₄</span> <span class="n">M</span><span class="o">]</span> <span class="o">:</span> <span class="n">SMul</span> <span class="n">ℕ</span> <span class="n">M</span> <span class="o">:=</span> <span class="o">⟨</span><span class="n">AddMonoid₄.nsmul</span><span class="o">⟩</span> <span class="kd">instance</span><span class="w"> </span><span class="n">mySMul</span><span class="w"> </span><span class="o">{</span><span class="n">M</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">AddMonoid₄</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">SMul</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">⟨</span><span class="n">AddMonoid₄.nsmul</span><span class="o">⟩</span> </pre></div> </div> <p>Let us check we can still construct a product monoid instance without providing the <code class="docutils literal notranslate"><span class="pre">nsmul</span></code> related fields.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span> <span class="o">(</span><span class="n">M</span> <span class="n">N</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">AddMonoid₄</span> <span class="n">M</span><span class="o">]</span> <span class="o">[</span><span class="n">AddMonoid₄</span> <span class="n">N</span><span class="o">]</span> <span class="o">:</span> <span class="n">AddMonoid₄</span> <span class="o">(</span><span class="n">M</span> <span class="bp">×</span> <span class="n">N</span><span class="o">)</span> <span class="n">where</span> <span class="n">add</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">p</span> <span class="n">q</span> <span class="bp">↦</span> <span class="o">(</span><span class="n">p.1</span> <span class="bp">+</span> <span class="n">q.1</span><span class="o">,</span> <span class="n">p.2</span> <span class="bp">+</span> <span class="n">q.2</span><span class="o">)</span> <span class="n">add_assoc₃</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="bp">↦</span> <span class="kd">by</span> <span class="n">ext</span> <span class="bp"><;></span> <span class="n">apply</span> <span class="n">add_assoc₃</span> <span class="n">zero</span> <span class="o">:=</span> <span class="o">(</span><span class="mi">0</span><span class="o">,</span> <span class="mi">0</span><span class="o">)</span> <span class="n">zero_add</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">a</span> <span class="bp">↦</span> <span class="kd">by</span> <span class="n">ext</span> <span class="bp"><;></span> <span class="n">apply</span> <span class="n">zero_add</span> <span class="n">add_zero</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">a</span> <span class="bp">↦</span> <span class="kd">by</span> <span class="n">ext</span> <span class="bp"><;></span> <span class="n">apply</span> <span class="n">add_zero</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span><span class="w"> </span><span class="o">(</span><span class="n">M</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">AddMonoid₄</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">AddMonoid₄</span><span class="w"> </span><span class="n">N</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">AddMonoid₄</span><span class="w"> </span><span class="o">(</span><span class="n">M</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">N</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="n">q</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">(</span><span class="n">p</span><span class="bp">.</span><span class="mi">1</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">q</span><span class="bp">.</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="n">p</span><span class="bp">.</span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">q</span><span class="bp">.</span><span class="mi">2</span><span class="o">)</span> <span class="w"> </span><span class="n">add_assoc₃</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">add_assoc₃</span> <span class="w"> </span><span class="n">zero</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span> <span class="w"> </span><span class="n">zero_add</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">zero_add</span> <span class="w"> </span><span class="n">add_zero</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">add_zero</span> </pre></div> </div> <p>And now let us handle the special case of <code class="docutils literal notranslate"><span class="pre">ℤ</span></code> where we want to build <code class="docutils literal notranslate"><span class="pre">nsmul</span></code> using the coercion of <code class="docutils literal notranslate"><span class="pre">ℕ</span></code> to <code class="docutils literal notranslate"><span class="pre">ℤ</span></code> and the multiplication on <code class="docutils literal notranslate"><span class="pre">ℤ</span></code>. Note in particular how the proof fields contain more work than in the default value above.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span> <span class="o">:</span> <span class="n">AddMonoid₄</span> <span class="n">ℤ</span> <span class="n">where</span> <span class="n">add</span> <span class="o">:=</span> <span class="o">(</span><span class="bp">·</span> <span class="bp">+</span> <span class="bp">·</span><span class="o">)</span> <span class="n">add_assoc₃</span> <span class="o">:=</span> <span class="n">Int.add_assoc</span> <span class="n">zero</span> <span class="o">:=</span> <span class="mi">0</span> <span class="n">zero_add</span> <span class="o">:=</span> <span class="n">Int.zero_add</span> <span class="n">add_zero</span> <span class="o">:=</span> <span class="n">Int.add_zero</span> <span class="n">nsmul</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">n</span> <span class="n">m</span> <span class="bp">↦</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℤ</span><span class="o">)</span> <span class="bp">*</span> <span class="n">m</span> <span class="n">nsmul_zero</span> <span class="o">:=</span> <span class="n">Int.zero_mul</span> <span class="n">nsmul_succ</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">n</span> <span class="n">m</span> <span class="bp">↦</span> <span class="k">show</span> <span class="o">(</span><span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span> <span class="o">:</span> <span class="n">ℤ</span><span class="o">)</span> <span class="bp">*</span> <span class="n">m</span> <span class="bp">=</span> <span class="n">m</span> <span class="bp">+</span> <span class="n">n</span> <span class="bp">*</span> <span class="n">m</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">Int.add_mul</span><span class="o">,</span> <span class="n">Int.add_comm</span><span class="o">,</span> <span class="n">Int.one_mul</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">AddMonoid₄</span><span class="w"> </span><span class="n">ℤ</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="bp">·</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="bp">·</span><span class="o">)</span> <span class="w"> </span><span class="n">add_assoc₃</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Int.add_assoc</span> <span class="w"> </span><span class="n">zero</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">0</span> <span class="w"> </span><span class="n">zero_add</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Int.zero_add</span> <span class="w"> </span><span class="n">add_zero</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Int.add_zero</span> <span class="w"> </span><span class="n">nsmul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℤ</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">m</span> <span class="w"> </span><span class="n">nsmul_zero</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Int.zero_mul</span> <span class="w"> </span><span class="n">nsmul_succ</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="k">show</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℤ</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">m</span> <span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">Int.add_mul</span><span class="o">,</span><span class="w"> </span><span class="n">Int.add_comm</span><span class="o">,</span><span class="w"> </span><span class="n">Int.one_mul</span><span class="o">]</span> </pre></div> </div> <p>Let us check we solved our issue. Because Lean already has a definition of scalar multiplication of a natural number and an integer, and we want to make sure our instance is used, we won’t use the <code class="docutils literal notranslate"><span class="pre">•</span></code> notation but call <code class="docutils literal notranslate"><span class="pre">SMul.mul</span></code> and explicitly provide our instance defined above.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">m</span> <span class="o">:</span> <span class="n">ℤ</span><span class="o">)</span> <span class="o">:</span> <span class="n">SMul.smul</span> <span class="o">(</span><span class="n">self</span> <span class="o">:=</span> <span class="n">mySMul</span><span class="o">)</span> <span class="n">n</span> <span class="n">m</span> <span class="bp">=</span> <span class="n">n</span> <span class="bp">*</span> <span class="n">m</span> <span class="o">:=</span> <span class="n">rfl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℤ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">SMul.smul</span><span class="w"> </span><span class="o">(</span><span class="n">self</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">mySMul</span><span class="o">)</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">rfl</span> </pre></div> </div> <p>This story then continues with incorporating a <code class="docutils literal notranslate"><span class="pre">zsmul</span></code> field into the definition of groups
-
@@ -638,16 +639,16 @@ <span id="section-hierarchies-morphisms"></span><h2><span class="section-number">7.2. </span>Morphisms<a class="headerlink" href="#morphisms" title="Link to this heading"></a></h2><p>So far in this chapter, we discussed how to create a hierarchy of mathematical structures. But defining structures is not really completed until we have morphisms. There are two main approaches here. The most obvious one is to define a predicate on functions.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">isMonoidHom₁</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">H</span><span class="o">]</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→</span> <span class="n">H</span><span class="o">)</span> <span class="o">:</span> <span class="kt">Prop</span> <span class="o">:=</span> <span class="n">f</span> <span class="mi">1</span> <span class="bp">=</span> <span class="mi">1</span> <span class="bp">∧</span> <span class="bp">∀</span> <span class="n">g</span> <span class="n">g'</span><span class="o">,</span> <span class="n">f</span> <span class="o">(</span><span class="n">g</span> <span class="bp">*</span> <span class="n">g'</span><span class="o">)</span> <span class="bp">=</span> <span class="n">f</span> <span class="n">g</span> <span class="bp">*</span> <span class="n">f</span> <span class="n">g'</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">isMonoidHom₁</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">H</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">g'</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g'</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g'</span> </pre></div> </div> <p>In this definition, it is a bit unpleasant to use a conjunction. In particular users will need to remember the ordering we chose when they want to access the two conditions. So we could use a structure instead.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">structure</span> <span class="n">isMonoidHom₂</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">H</span><span class="o">]</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→</span> <span class="n">H</span><span class="o">)</span> <span class="o">:</span> <span class="kt">Prop</span> <span class="n">where</span> <span class="n">map_one</span> <span class="o">:</span> <span class="n">f</span> <span class="mi">1</span> <span class="bp">=</span> <span class="mi">1</span> <span class="n">map_mul</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">g</span> <span class="n">g'</span><span class="o">,</span> <span class="n">f</span> <span class="o">(</span><span class="n">g</span> <span class="bp">*</span> <span class="n">g'</span><span class="o">)</span> <span class="bp">=</span> <span class="n">f</span> <span class="n">g</span> <span class="bp">*</span> <span class="n">f</span> <span class="n">g'</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">structure</span><span class="w"> </span><span class="n">isMonoidHom₂</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">H</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">map_one</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span> <span class="w"> </span><span class="n">map_mul</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">g'</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g'</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g'</span> </pre></div> </div> <p>Once we are here, it is even tempting to make it a class and use the type class instance resolution
-
@@ -665,17 +666,17 @@ It really feels like “monoid morphism” is not an adjective you can assign to a bare function,it is a noun. On the other hand one can argue that a continuous function between topological spaces is really a function that happens to be continuous. This is one reason why Mathlib has a <code class="docutils literal notranslate"><span class="pre">Continuous</span></code> predicate. For instance you can write:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="o">(</span><span class="n">id</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:=</span> <span class="n">continuous_id</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="o">(</span><span class="n">id</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">continuous_id</span> </pre></div> </div> <p>We still have bundles of continuous functions, which are convenient for instance to put a topology on a space of continuous functions, but they are not the primary tool to work with continuity.</p> <p>By contrast, morphisms between monoids (or other algebraic structures) are bundled as in:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">@[</span><span class="n">ext</span><span class="kd">]</span> <span class="kd">structure</span> <span class="n">MonoidHom₁</span> <span class="o">(</span><span class="n">G</span> <span class="n">H</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">H</span><span class="o">]</span> <span class="n">where</span> <span class="n">toFun</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→</span> <span class="n">H</span> <span class="n">map_one</span> <span class="o">:</span> <span class="n">toFun</span> <span class="mi">1</span> <span class="bp">=</span> <span class="mi">1</span> <span class="n">map_mul</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">g</span> <span class="n">g'</span><span class="o">,</span> <span class="n">toFun</span> <span class="o">(</span><span class="n">g</span> <span class="bp">*</span> <span class="n">g'</span><span class="o">)</span> <span class="bp">=</span> <span class="n">toFun</span> <span class="n">g</span> <span class="bp">*</span> <span class="n">toFun</span> <span class="n">g'</span> <span class="kd">structure</span><span class="w"> </span><span class="n">MonoidHom₁</span><span class="w"> </span><span class="o">(</span><span class="n">G</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">H</span><span class="o">]</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">H</span> <span class="w"> </span><span class="n">map_one</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span> <span class="w"> </span><span class="n">map_mul</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">g'</span><span class="o">,</span><span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g'</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="n">g'</span> </pre></div> </div> <p>Of course we don’t want to type <code class="docutils literal notranslate"><span class="pre">toFun</span></code> everywhere so we register a coercion using
-
@@ -683,30 +684,30 @@ the <code class="docutils literal notranslate"><span class="pre">CoeFun</span></code> type class. Its first argument is the type we want to coerce to a function.The second argument describes the target function type. In our case it is always <code class="docutils literal notranslate"><span class="pre">G</span> <span class="pre">→</span> <span class="pre">H</span></code> for every <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">:</span> <span class="pre">MonoidHom₁</span> <span class="pre">G</span> <span class="pre">H</span></code>. We also tag <code class="docutils literal notranslate"><span class="pre">MonoidHom₁.toFun</span></code> with the <code class="docutils literal notranslate"><span class="pre">coe</span></code> attribute to make sure it is displayed almost invisibly in the tactic state, simply by a <code class="docutils literal notranslate"><span class="pre">↑</span></code> prefix.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">H</span><span class="o">]</span> <span class="o">:</span> <span class="n">CoeFun</span> <span class="o">(</span><span class="n">MonoidHom₁</span> <span class="n">G</span> <span class="n">H</span><span class="o">)</span> <span class="o">(</span><span class="k">fun</span> <span class="n">_</span> <span class="bp">↦</span> <span class="n">G</span> <span class="bp">→</span> <span class="n">H</span><span class="o">)</span> <span class="n">where</span> <span class="n">coe</span> <span class="o">:=</span> <span class="n">MonoidHom₁.toFun</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">H</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">CoeFun</span><span class="w"> </span><span class="o">(</span><span class="n">MonoidHom₁</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">coe</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">MonoidHom₁.toFun</span> <span class="kn">attribute</span> <span class="o">[</span><span class="n">coe</span><span class="o">]</span> <span class="n">MonoidHom₁.toFun</span> <span class="kn">attribute</span><span class="w"> </span><span class="o">[</span><span class="n">coe</span><span class="o">]</span><span class="w"> </span><span class="n">MonoidHom₁.toFun</span> </pre></div> </div> <p>Let us check we can indeed apply a bundled monoid morphism to an element.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">H</span><span class="o">]</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">MonoidHom₁</span> <span class="n">G</span> <span class="n">H</span><span class="o">)</span> <span class="o">:</span> <span class="n">f</span> <span class="mi">1</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="n">f.map_one</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">H</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MonoidHom₁</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">f.map_one</span> </pre></div> </div> <p>We can do the same with other kind of morphisms until we reach ring morphisms.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">@[</span><span class="n">ext</span><span class="kd">]</span> <span class="kd">structure</span> <span class="n">AddMonoidHom₁</span> <span class="o">(</span><span class="n">G</span> <span class="n">H</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">AddMonoid</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">AddMonoid</span> <span class="n">H</span><span class="o">]</span> <span class="n">where</span> <span class="n">toFun</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→</span> <span class="n">H</span> <span class="n">map_zero</span> <span class="o">:</span> <span class="n">toFun</span> <span class="mi">0</span> <span class="bp">=</span> <span class="mi">0</span> <span class="n">map_add</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">g</span> <span class="n">g'</span><span class="o">,</span> <span class="n">toFun</span> <span class="o">(</span><span class="n">g</span> <span class="bp">+</span> <span class="n">g'</span><span class="o">)</span> <span class="bp">=</span> <span class="n">toFun</span> <span class="n">g</span> <span class="bp">+</span> <span class="n">toFun</span> <span class="n">g'</span> <span class="kd">structure</span><span class="w"> </span><span class="n">AddMonoidHom₁</span><span class="w"> </span><span class="o">(</span><span class="n">G</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">AddMonoid</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">AddMonoid</span><span class="w"> </span><span class="n">H</span><span class="o">]</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">H</span> <span class="w"> </span><span class="n">map_zero</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span> <span class="w"> </span><span class="n">map_add</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">g'</span><span class="o">,</span><span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g'</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="n">g'</span> <span class="kd">instance</span> <span class="o">[</span><span class="n">AddMonoid</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">AddMonoid</span> <span class="n">H</span><span class="o">]</span> <span class="o">:</span> <span class="n">CoeFun</span> <span class="o">(</span><span class="n">AddMonoidHom₁</span> <span class="n">G</span> <span class="n">H</span><span class="o">)</span> <span class="o">(</span><span class="k">fun</span> <span class="n">_</span> <span class="bp">↦</span> <span class="n">G</span> <span class="bp">→</span> <span class="n">H</span><span class="o">)</span> <span class="n">where</span> <span class="n">coe</span> <span class="o">:=</span> <span class="n">AddMonoidHom₁.toFun</span> <span class="kd">instance</span><span class="w"> </span><span class="o">[</span><span class="n">AddMonoid</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">AddMonoid</span><span class="w"> </span><span class="n">H</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">CoeFun</span><span class="w"> </span><span class="o">(</span><span class="n">AddMonoidHom₁</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">coe</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">AddMonoidHom₁.toFun</span> <span class="kn">attribute</span> <span class="o">[</span><span class="n">coe</span><span class="o">]</span> <span class="n">AddMonoidHom₁.toFun</span> <span class="kn">attribute</span><span class="w"> </span><span class="o">[</span><span class="n">coe</span><span class="o">]</span><span class="w"> </span><span class="n">AddMonoidHom₁.toFun</span> <span class="kd">@[</span><span class="n">ext</span><span class="kd">]</span> <span class="kd">structure</span> <span class="n">RingHom₁</span> <span class="o">(</span><span class="n">R</span> <span class="n">S</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">Ring</span> <span class="n">R</span><span class="o">]</span> <span class="o">[</span><span class="n">Ring</span> <span class="n">S</span><span class="o">]</span> <span class="kd">extends</span> <span class="n">MonoidHom₁</span> <span class="n">R</span> <span class="n">S</span><span class="o">,</span> <span class="n">AddMonoidHom₁</span> <span class="n">R</span> <span class="n">S</span> <span class="kd">structure</span><span class="w"> </span><span class="n">RingHom₁</span><span class="w"> </span><span class="o">(</span><span class="n">R</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">Ring</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Ring</span><span class="w"> </span><span class="n">S</span><span class="o">]</span><span class="w"> </span><span class="kd">extends</span><span class="w"> </span><span class="n">MonoidHom₁</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="n">S</span><span class="o">,</span><span class="w"> </span><span class="n">AddMonoidHom₁</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="n">S</span> </pre></div> </div> <p>There are a couple of issues about this approach. A minor one is we don’t quite know where to put
-
@@ -720,16 +721,16 @@ Neither option is appealing so Mathlib uses a new hierarchy trick here. The idea is to definea type class for objects that are at least monoid morphisms, instantiate that class with both monoid morphisms and ring morphisms and use it to state every lemma. In the definition below, <code class="docutils literal notranslate"><span class="pre">F</span></code> could be <code class="docutils literal notranslate"><span class="pre">MonoidHom₁</span> <span class="pre">M</span> <span class="pre">N</span></code>, or <code class="docutils literal notranslate"><span class="pre">RingHom₁</span> <span class="pre">M</span> <span class="pre">N</span></code> if <code class="docutils literal notranslate"><span class="pre">M</span></code> and <code class="docutils literal notranslate"><span class="pre">N</span></code> have a ring structure.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span> <span class="n">MonoidHomClass₁</span> <span class="o">(</span><span class="n">F</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">(</span><span class="n">M</span> <span class="n">N</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">N</span><span class="o">]</span> <span class="n">where</span> <span class="n">toFun</span> <span class="o">:</span> <span class="n">F</span> <span class="bp">→</span> <span class="n">M</span> <span class="bp">→</span> <span class="n">N</span> <span class="n">map_one</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">f</span> <span class="o">:</span> <span class="n">F</span><span class="o">,</span> <span class="n">toFun</span> <span class="n">f</span> <span class="mi">1</span> <span class="bp">=</span> <span class="mi">1</span> <span class="n">map_mul</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">f</span> <span class="n">g</span> <span class="n">g'</span><span class="o">,</span> <span class="n">toFun</span> <span class="n">f</span> <span class="o">(</span><span class="n">g</span> <span class="bp">*</span> <span class="n">g'</span><span class="o">)</span> <span class="bp">=</span> <span class="n">toFun</span> <span class="n">f</span> <span class="n">g</span> <span class="bp">*</span> <span class="n">toFun</span> <span class="n">f</span> <span class="n">g'</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span><span class="w"> </span><span class="n">MonoidHomClass₁</span><span class="w"> </span><span class="o">(</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">M</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">N</span><span class="o">]</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">N</span> <span class="w"> </span><span class="n">map_one</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">F</span><span class="o">,</span><span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span> <span class="w"> </span><span class="n">map_mul</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">g'</span><span class="o">,</span><span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g'</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g'</span> </pre></div> </div> <p>However there is a problem with the above implementation. We haven’t registered a coercion to function instance yet. Let us try to do it now.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">badInst</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">N</span><span class="o">]</span> <span class="o">[</span><span class="n">MonoidHomClass₁</span> <span class="n">F</span> <span class="n">M</span> <span class="n">N</span><span class="o">]</span> <span class="o">:</span> <span class="n">CoeFun</span> <span class="n">F</span> <span class="o">(</span><span class="k">fun</span> <span class="n">_</span> <span class="bp">↦</span> <span class="n">M</span> <span class="bp">→</span> <span class="n">N</span><span class="o">)</span> <span class="n">where</span> <span class="n">coe</span> <span class="o">:=</span> <span class="n">MonoidHomClass₁.toFun</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">badInst</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">N</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">MonoidHomClass₁</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="n">N</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">CoeFun</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">N</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">coe</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">MonoidHomClass₁.toFun</span> </pre></div> </div> <p>Making this an instance would be bad. When faced with something like <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">x</span></code> where the type of <code class="docutils literal notranslate"><span class="pre">f</span></code>
-
@@ -747,41 +748,41 @@ <p>Here the solution is easy, we need to tell Lean to first search what is <code class="docutils literal notranslate"><span class="pre">F</span></code> and then deduce <code class="docutils literal notranslate"><span class="pre">M</span></code>and <code class="docutils literal notranslate"><span class="pre">N</span></code>. This is done using the <code class="docutils literal notranslate"><span class="pre">outParam</span></code> function. This function is defined as the identity function, but is still recognized by the type class machinery and triggers the desired behavior. Hence we can retry defining our class, paying attention to the <code class="docutils literal notranslate"><span class="pre">outParam</span></code> function:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span> <span class="n">MonoidHomClass₂</span> <span class="o">(</span><span class="n">F</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">(</span><span class="n">M</span> <span class="n">N</span> <span class="o">:</span> <span class="n">outParam</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">N</span><span class="o">]</span> <span class="n">where</span> <span class="n">toFun</span> <span class="o">:</span> <span class="n">F</span> <span class="bp">→</span> <span class="n">M</span> <span class="bp">→</span> <span class="n">N</span> <span class="n">map_one</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">f</span> <span class="o">:</span> <span class="n">F</span><span class="o">,</span> <span class="n">toFun</span> <span class="n">f</span> <span class="mi">1</span> <span class="bp">=</span> <span class="mi">1</span> <span class="n">map_mul</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">f</span> <span class="n">g</span> <span class="n">g'</span><span class="o">,</span> <span class="n">toFun</span> <span class="n">f</span> <span class="o">(</span><span class="n">g</span> <span class="bp">*</span> <span class="n">g'</span><span class="o">)</span> <span class="bp">=</span> <span class="n">toFun</span> <span class="n">f</span> <span class="n">g</span> <span class="bp">*</span> <span class="n">toFun</span> <span class="n">f</span> <span class="n">g'</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span><span class="w"> </span><span class="n">MonoidHomClass₂</span><span class="w"> </span><span class="o">(</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">M</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">outParam</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">N</span><span class="o">]</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">N</span> <span class="w"> </span><span class="n">map_one</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">F</span><span class="o">,</span><span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span> <span class="w"> </span><span class="n">map_mul</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">g'</span><span class="o">,</span><span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g'</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g'</span> <span class="kd">instance</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">N</span><span class="o">]</span> <span class="o">[</span><span class="n">MonoidHomClass₂</span> <span class="n">F</span> <span class="n">M</span> <span class="n">N</span><span class="o">]</span> <span class="o">:</span> <span class="n">CoeFun</span> <span class="n">F</span> <span class="o">(</span><span class="k">fun</span> <span class="n">_</span> <span class="bp">↦</span> <span class="n">M</span> <span class="bp">→</span> <span class="n">N</span><span class="o">)</span> <span class="n">where</span> <span class="n">coe</span> <span class="o">:=</span> <span class="n">MonoidHomClass₂.toFun</span> <span class="kd">instance</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">N</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">MonoidHomClass₂</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="n">N</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">CoeFun</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">N</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">coe</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">MonoidHomClass₂.toFun</span> <span class="kn">attribute</span> <span class="o">[</span><span class="n">coe</span><span class="o">]</span> <span class="n">MonoidHomClass₂.toFun</span> <span class="kn">attribute</span><span class="w"> </span><span class="o">[</span><span class="n">coe</span><span class="o">]</span><span class="w"> </span><span class="n">MonoidHomClass₂.toFun</span> </pre></div> </div> <p>Now we can proceed with our plan to instantiate this class.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span> <span class="o">(</span><span class="n">M</span> <span class="n">N</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">N</span><span class="o">]</span> <span class="o">:</span> <span class="n">MonoidHomClass₂</span> <span class="o">(</span><span class="n">MonoidHom₁</span> <span class="n">M</span> <span class="n">N</span><span class="o">)</span> <span class="n">M</span> <span class="n">N</span> <span class="n">where</span> <span class="n">toFun</span> <span class="o">:=</span> <span class="n">MonoidHom₁.toFun</span> <span class="n">map_one</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">f</span> <span class="bp">↦</span> <span class="n">f.map_one</span> <span class="n">map_mul</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">f</span> <span class="bp">↦</span> <span class="n">f.map_mul</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span><span class="w"> </span><span class="o">(</span><span class="n">M</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">N</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MonoidHomClass₂</span><span class="w"> </span><span class="o">(</span><span class="n">MonoidHom₁</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="n">N</span><span class="o">)</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">MonoidHom₁.toFun</span> <span class="w"> </span><span class="n">map_one</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f.map_one</span> <span class="w"> </span><span class="n">map_mul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f.map_mul</span> <span class="kd">instance</span> <span class="o">(</span><span class="n">R</span> <span class="n">S</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">Ring</span> <span class="n">R</span><span class="o">]</span> <span class="o">[</span><span class="n">Ring</span> <span class="n">S</span><span class="o">]</span> <span class="o">:</span> <span class="n">MonoidHomClass₂</span> <span class="o">(</span><span class="n">RingHom₁</span> <span class="n">R</span> <span class="n">S</span><span class="o">)</span> <span class="n">R</span> <span class="n">S</span> <span class="n">where</span> <span class="n">toFun</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">f</span> <span class="bp">↦</span> <span class="n">f.toMonoidHom₁.toFun</span> <span class="n">map_one</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">f</span> <span class="bp">↦</span> <span class="n">f.toMonoidHom₁.map_one</span> <span class="n">map_mul</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">f</span> <span class="bp">↦</span> <span class="n">f.toMonoidHom₁.map_mul</span> <span class="kd">instance</span><span class="w"> </span><span class="o">(</span><span class="n">R</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">Ring</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Ring</span><span class="w"> </span><span class="n">S</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MonoidHomClass₂</span><span class="w"> </span><span class="o">(</span><span class="n">RingHom₁</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="n">S</span><span class="o">)</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f.toMonoidHom₁.toFun</span> <span class="w"> </span><span class="n">map_one</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f.toMonoidHom₁.map_one</span> <span class="w"> </span><span class="n">map_mul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f.toMonoidHom₁.map_mul</span> </pre></div> </div> <p>As promised every lemma we prove about <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">:</span> <span class="pre">F</span></code> assuming an instance of <code class="docutils literal notranslate"><span class="pre">MonoidHomClass₁</span> <span class="pre">F</span></code> will apply both to monoid morphisms and ring morphisms. Let us see an example lemma and check it applies to both situations.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">lemma</span> <span class="n">map_inv_of_inv</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">N</span><span class="o">]</span> <span class="o">[</span><span class="n">MonoidHomClass₂</span> <span class="n">F</span> <span class="n">M</span> <span class="n">N</span><span class="o">]</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">F</span><span class="o">)</span> <span class="o">{</span><span class="n">m</span> <span class="n">m'</span> <span class="o">:</span> <span class="n">M</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">m</span><span class="bp">*</span><span class="n">m'</span> <span class="bp">=</span> <span class="mi">1</span><span class="o">)</span> <span class="o">:</span> <span class="n">f</span> <span class="n">m</span> <span class="bp">*</span> <span class="n">f</span> <span class="n">m'</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="bp">←</span> <span class="n">MonoidHomClass₂.map_mul</span><span class="o">,</span> <span class="n">h</span><span class="o">,</span> <span class="n">MonoidHomClass₂.map_one</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">lemma</span><span class="w"> </span><span class="n">map_inv_of_inv</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">N</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">MonoidHomClass₂</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="n">N</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">m</span><span class="w"> </span><span class="n">m'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="bp">*</span><span class="n">m'</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">m'</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="bp">←</span><span class="w"> </span><span class="n">MonoidHomClass₂.map_mul</span><span class="o">,</span><span class="w"> </span><span class="n">h</span><span class="o">,</span><span class="w"> </span><span class="n">MonoidHomClass₂.map_one</span><span class="o">]</span> <span class="kd">example</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">N</span><span class="o">]</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">MonoidHom₁</span> <span class="n">M</span> <span class="n">N</span><span class="o">)</span> <span class="o">{</span><span class="n">m</span> <span class="n">m'</span> <span class="o">:</span> <span class="n">M</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">m</span><span class="bp">*</span><span class="n">m'</span> <span class="bp">=</span> <span class="mi">1</span><span class="o">)</span> <span class="o">:</span> <span class="n">f</span> <span class="n">m</span> <span class="bp">*</span> <span class="n">f</span> <span class="n">m'</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="n">map_inv_of_inv</span> <span class="n">f</span> <span class="n">h</span> <span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">N</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MonoidHom₁</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="n">N</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">m</span><span class="w"> </span><span class="n">m'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">m</span><span class="bp">*</span><span class="n">m'</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">m'</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span> <span class="n">map_inv_of_inv</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">h</span> <span class="kd">example</span> <span class="o">[</span><span class="n">Ring</span> <span class="n">R</span><span class="o">]</span> <span class="o">[</span><span class="n">Ring</span> <span class="n">S</span><span class="o">]</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">RingHom₁</span> <span class="n">R</span> <span class="n">S</span><span class="o">)</span> <span class="o">{</span><span class="n">r</span> <span class="n">r'</span> <span class="o">:</span> <span class="n">R</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">r</span><span class="bp">*</span><span class="n">r'</span> <span class="bp">=</span> <span class="mi">1</span><span class="o">)</span> <span class="o">:</span> <span class="n">f</span> <span class="n">r</span> <span class="bp">*</span> <span class="n">f</span> <span class="n">r'</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="n">map_inv_of_inv</span> <span class="n">f</span> <span class="n">h</span> <span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">Ring</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Ring</span><span class="w"> </span><span class="n">S</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">RingHom₁</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="n">S</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">r</span><span class="w"> </span><span class="n">r'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">r</span><span class="bp">*</span><span class="n">r'</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">r'</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span> <span class="n">map_inv_of_inv</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>At first sight, it may look like we got back to our old bad idea of making <code class="docutils literal notranslate"><span class="pre">MonoidHom₁</span></code> a class.
-
@@ -794,16 +795,16 @@ to record that this pattern is used only for functions with extra properties, meaning that thecoercion to functions should be injective. So Mathlib adds one more layer of abstraction with the base class <code class="docutils literal notranslate"><span class="pre">DFunLike</span></code> (where “DFun” stands for dependent function). Let us redefine our <code class="docutils literal notranslate"><span class="pre">MonoidHomClass</span></code> on top of this base layer.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span> <span class="n">MonoidHomClass₃</span> <span class="o">(</span><span class="n">F</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">(</span><span class="n">M</span> <span class="n">N</span> <span class="o">:</span> <span class="n">outParam</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">N</span><span class="o">]</span> <span class="kd">extends</span> <span class="n">DFunLike</span> <span class="n">F</span> <span class="n">M</span> <span class="o">(</span><span class="k">fun</span> <span class="n">_</span> <span class="bp">↦</span> <span class="n">N</span><span class="o">)</span> <span class="n">where</span> <span class="n">map_one</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">f</span> <span class="o">:</span> <span class="n">F</span><span class="o">,</span> <span class="n">f</span> <span class="mi">1</span> <span class="bp">=</span> <span class="mi">1</span> <span class="n">map_mul</span> <span class="o">:</span> <span class="bp">∀</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">F</span><span class="o">)</span> <span class="n">g</span> <span class="n">g'</span><span class="o">,</span> <span class="n">f</span> <span class="o">(</span><span class="n">g</span> <span class="bp">*</span> <span class="n">g'</span><span class="o">)</span> <span class="bp">=</span> <span class="n">f</span> <span class="n">g</span> <span class="bp">*</span> <span class="n">f</span> <span class="n">g'</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span><span class="w"> </span><span class="n">MonoidHomClass₃</span><span class="w"> </span><span class="o">(</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">M</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">outParam</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">N</span><span class="o">]</span><span class="w"> </span><span class="kd">extends</span> <span class="w"> </span><span class="n">DFunLike</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">N</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">map_one</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">F</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span> <span class="w"> </span><span class="n">map_mul</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">g'</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g'</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g'</span> <span class="kd">instance</span> <span class="o">(</span><span class="n">M</span> <span class="n">N</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">N</span><span class="o">]</span> <span class="o">:</span> <span class="n">MonoidHomClass₃</span> <span class="o">(</span><span class="n">MonoidHom₁</span> <span class="n">M</span> <span class="n">N</span><span class="o">)</span> <span class="n">M</span> <span class="n">N</span> <span class="n">where</span> <span class="n">coe</span> <span class="o">:=</span> <span class="n">MonoidHom₁.toFun</span> <span class="n">coe_injective'</span> <span class="n">_</span> <span class="n">_</span> <span class="o">:=</span> <span class="n">MonoidHom₁.ext</span> <span class="n">map_one</span> <span class="o">:=</span> <span class="n">MonoidHom₁.map_one</span> <span class="n">map_mul</span> <span class="o">:=</span> <span class="n">MonoidHom₁.map_mul</span> <span class="kd">instance</span><span class="w"> </span><span class="o">(</span><span class="n">M</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">N</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MonoidHomClass₃</span><span class="w"> </span><span class="o">(</span><span class="n">MonoidHom₁</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="n">N</span><span class="o">)</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">coe</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">MonoidHom₁.toFun</span> <span class="w"> </span><span class="n">coe_injective'</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">MonoidHom₁.ext</span> <span class="w"> </span><span class="n">map_one</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">MonoidHom₁.map_one</span> <span class="w"> </span><span class="n">map_mul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">MonoidHom₁.map_mul</span> </pre></div> </div> <p>Of course the hierarchy of morphisms does not stop here. We could go on and define a class
-
@@ -817,24 +818,24 @@ Like continuous functions, order preserving functions are primarily unbundled in Mathlib wherethey are defined by the <code class="docutils literal notranslate"><span class="pre">Monotone</span></code> predicate. Of course you need to complete the class definitions below.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">@[</span><span class="n">ext</span><span class="kd">]</span> <span class="kd">structure</span> <span class="n">OrderPresHom</span> <span class="o">(</span><span class="n">α</span> <span class="n">β</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">LE</span> <span class="n">α</span><span class="o">]</span> <span class="o">[</span><span class="n">LE</span> <span class="n">β</span><span class="o">]</span> <span class="n">where</span> <span class="n">toFun</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">β</span> <span class="n">le_of_le</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="n">a'</span><span class="o">,</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">a'</span> <span class="bp">→</span> <span class="n">toFun</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">toFun</span> <span class="n">a'</span> <span class="kd">structure</span><span class="w"> </span><span class="n">OrderPresHom</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">LE</span><span class="w"> </span><span class="n">α</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">LE</span><span class="w"> </span><span class="n">β</span><span class="o">]</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">β</span> <span class="w"> </span><span class="n">le_of_le</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">a'</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">a'</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="n">a'</span> <span class="kd">@[</span><span class="n">ext</span><span class="kd">]</span> <span class="kd">structure</span> <span class="n">OrderPresMonoidHom</span> <span class="o">(</span><span class="n">M</span> <span class="n">N</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">[</span><span class="n">LE</span> <span class="n">M</span><span class="o">]</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">N</span><span class="o">]</span> <span class="o">[</span><span class="n">LE</span> <span class="n">N</span><span class="o">]</span> <span class="kd">extends</span> <span class="n">MonoidHom₁</span> <span class="n">M</span> <span class="n">N</span><span class="o">,</span> <span class="n">OrderPresHom</span> <span class="n">M</span> <span class="n">N</span> <span class="kd">structure</span><span class="w"> </span><span class="n">OrderPresMonoidHom</span><span class="w"> </span><span class="o">(</span><span class="n">M</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">LE</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">N</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">LE</span><span class="w"> </span><span class="n">N</span><span class="o">]</span><span class="w"> </span><span class="kd">extends</span> <span class="n">MonoidHom₁</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="n">OrderPresHom</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="n">N</span> <span class="kd">class</span> <span class="n">OrderPresHomClass</span> <span class="o">(</span><span class="n">F</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">(</span><span class="n">α</span> <span class="n">β</span> <span class="o">:</span> <span class="n">outParam</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">LE</span> <span class="n">α</span><span class="o">]</span> <span class="o">[</span><span class="n">LE</span> <span class="n">β</span><span class="o">]</span> <span class="kd">class</span><span class="w"> </span><span class="n">OrderPresHomClass</span><span class="w"> </span><span class="o">(</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">outParam</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">LE</span><span class="w"> </span><span class="n">α</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">LE</span><span class="w"> </span><span class="n">β</span><span class="o">]</span> <span class="kd">instance</span> <span class="o">(</span><span class="n">α</span> <span class="n">β</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">LE</span> <span class="n">α</span><span class="o">]</span> <span class="o">[</span><span class="n">LE</span> <span class="n">β</span><span class="o">]</span> <span class="o">:</span> <span class="n">OrderPresHomClass</span> <span class="o">(</span><span class="n">OrderPresHom</span> <span class="n">α</span> <span class="n">β</span><span class="o">)</span> <span class="n">α</span> <span class="n">β</span> <span class="n">where</span> <span class="kd">instance</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">LE</span><span class="w"> </span><span class="n">α</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">LE</span><span class="w"> </span><span class="n">β</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">OrderPresHomClass</span><span class="w"> </span><span class="o">(</span><span class="n">OrderPresHom</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="n">β</span><span class="o">)</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="n">where</span> <span class="kd">instance</span> <span class="o">(</span><span class="n">α</span> <span class="n">β</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">LE</span> <span class="n">α</span><span class="o">]</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">α</span><span class="o">]</span> <span class="o">[</span><span class="n">LE</span> <span class="n">β</span><span class="o">]</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">β</span><span class="o">]</span> <span class="o">:</span> <span class="n">OrderPresHomClass</span> <span class="o">(</span><span class="n">OrderPresMonoidHom</span> <span class="n">α</span> <span class="n">β</span><span class="o">)</span> <span class="n">α</span> <span class="n">β</span> <span class="n">where</span> <span class="kd">instance</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">LE</span><span class="w"> </span><span class="n">α</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">α</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">LE</span><span class="w"> </span><span class="n">β</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">β</span><span class="o">]</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">OrderPresHomClass</span><span class="w"> </span><span class="o">(</span><span class="n">OrderPresMonoidHom</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="n">β</span><span class="o">)</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="n">where</span> <span class="kd">instance</span> <span class="o">(</span><span class="n">α</span> <span class="n">β</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">LE</span> <span class="n">α</span><span class="o">]</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">α</span><span class="o">]</span> <span class="o">[</span><span class="n">LE</span> <span class="n">β</span><span class="o">]</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">β</span><span class="o">]</span> <span class="o">:</span> <span class="n">MonoidHomClass₃</span> <span class="o">(</span><span class="n">OrderPresMonoidHom</span> <span class="n">α</span> <span class="n">β</span><span class="o">)</span> <span class="n">α</span> <span class="n">β</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">instance</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">LE</span><span class="w"> </span><span class="n">α</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">α</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">LE</span><span class="w"> </span><span class="n">β</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">β</span><span class="o">]</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">MonoidHomClass₃</span><span class="w"> </span><span class="o">(</span><span class="n">OrderPresMonoidHom</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="n">β</span><span class="o">)</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="n">β</span> <span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> </section>
-
@@ -850,65 +851,65 @@ to <code class="docutils literal notranslate"><span class="pre">X</span> <span class="pre">→</span> <span class="pre">Prop</span></code>. Instead there is a <code class="docutils literal notranslate"><span class="pre">SetLike</span></code> class. Instead of wrapping an injection into afunction type, that class wraps an injection into a <code class="docutils literal notranslate"><span class="pre">Set</span></code> type and defines the corresponding coercion and <code class="docutils literal notranslate"><span class="pre">Membership</span></code> instance.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">@[</span><span class="n">ext</span><span class="kd">]</span> <span class="kd">structure</span> <span class="n">Submonoid₁</span> <span class="o">(</span><span class="n">M</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="n">where</span> <span class="sd">/-- The carrier of a submonoid. -/</span> <span class="n">carrier</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">M</span> <span class="sd">/-- The product of two elements of a submonoid belongs to the submonoid. -/</span> <span class="n">mul_mem</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span><span class="o">}</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">∈</span> <span class="n">carrier</span> <span class="bp">→</span> <span class="n">b</span> <span class="bp">∈</span> <span class="n">carrier</span> <span class="bp">→</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">∈</span> <span class="n">carrier</span> <span class="sd">/-- The unit element belongs to the submonoid. -/</span> <span class="n">one_mem</span> <span class="o">:</span> <span class="mi">1</span> <span class="bp">∈</span> <span class="n">carrier</span> <span class="kd">structure</span><span class="w"> </span><span class="n">Submonoid₁</span><span class="w"> </span><span class="o">(</span><span class="n">M</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="sd">/-- The carrier of a submonoid. -/</span> <span class="w"> </span><span class="n">carrier</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">M</span> <span class="w"> </span><span class="sd">/-- The product of two elements of a submonoid belongs to the submonoid. -/</span> <span class="w"> </span><span class="n">mul_mem</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">carrier</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">carrier</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">carrier</span> <span class="w"> </span><span class="sd">/-- The unit element belongs to the submonoid. -/</span> <span class="w"> </span><span class="n">one_mem</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">carrier</span> <span class="sd">/-- Submonoids in `M` can be seen as sets in `M`. -/</span> <span class="kd">instance</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">:</span> <span class="n">SetLike</span> <span class="o">(</span><span class="n">Submonoid₁</span> <span class="n">M</span><span class="o">)</span> <span class="n">M</span> <span class="n">where</span> <span class="n">coe</span> <span class="o">:=</span> <span class="n">Submonoid₁.carrier</span> <span class="n">coe_injective'</span> <span class="n">_</span> <span class="n">_</span> <span class="o">:=</span> <span class="n">Submonoid₁.ext</span> <span class="kd">instance</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">SetLike</span><span class="w"> </span><span class="o">(</span><span class="n">Submonoid₁</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">coe</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Submonoid₁.carrier</span> <span class="w"> </span><span class="n">coe_injective'</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Submonoid₁.ext</span> </pre></div> </div> <p>Equipped with the above <code class="docutils literal notranslate"><span class="pre">SetLike</span></code> instance, we can already state naturally that a submonoid <code class="docutils literal notranslate"><span class="pre">N</span></code> contains <code class="docutils literal notranslate"><span class="pre">1</span></code> without using <code class="docutils literal notranslate"><span class="pre">N.carrier</span></code>. We can also silently treat <code class="docutils literal notranslate"><span class="pre">N</span></code> as a set in <code class="docutils literal notranslate"><span class="pre">M</span></code> as take its direct image under a map.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">(</span><span class="n">N</span> <span class="o">:</span> <span class="n">Submonoid₁</span> <span class="n">M</span><span class="o">)</span> <span class="o">:</span> <span class="mi">1</span> <span class="bp">∈</span> <span class="n">N</span> <span class="o">:=</span> <span class="n">N.one_mem</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submonoid₁</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">N.one_mem</span> <span class="kd">example</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">(</span><span class="n">N</span> <span class="o">:</span> <span class="n">Submonoid₁</span> <span class="n">M</span><span class="o">)</span> <span class="o">(</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">M</span> <span class="bp">→</span> <span class="n">α</span><span class="o">)</span> <span class="o">:=</span> <span class="n">f</span> <span class="bp">''</span> <span class="n">N</span> <span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submonoid₁</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">N</span> </pre></div> </div> <p>We also have a coercion to <code class="docutils literal notranslate"><span class="pre">Type</span></code> which uses <code class="docutils literal notranslate"><span class="pre">Subtype</span></code> so, given a submonoid <code class="docutils literal notranslate"><span class="pre">N</span></code> we can write a parameter <code class="docutils literal notranslate"><span class="pre">(x</span> <span class="pre">:</span> <span class="pre">N)</span></code> which can be coerced to an element of <code class="docutils literal notranslate"><span class="pre">M</span></code> belonging to <code class="docutils literal notranslate"><span class="pre">N</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">(</span><span class="n">N</span> <span class="o">:</span> <span class="n">Submonoid₁</span> <span class="n">M</span><span class="o">)</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">N</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">M</span><span class="o">)</span> <span class="bp">∈</span> <span class="n">N</span> <span class="o">:=</span> <span class="n">x.property</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submonoid₁</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">N</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">x.property</span> </pre></div> </div> <p>Using this coercion to <code class="docutils literal notranslate"><span class="pre">Type</span></code> we can also tackle the task of equipping a submonoid with a monoid structure. We will use the coercion from the type associated to <code class="docutils literal notranslate"><span class="pre">N</span></code> as above, and the lemma <code class="docutils literal notranslate"><span class="pre">SetCoe.ext</span></code> asserting this coercion is injective. Both are provided by the <code class="docutils literal notranslate"><span class="pre">SetLike</span></code> instance.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span> <span class="n">SubMonoid₁Monoid</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">(</span><span class="n">N</span> <span class="o">:</span> <span class="n">Submonoid₁</span> <span class="n">M</span><span class="o">)</span> <span class="o">:</span> <span class="n">Monoid</span> <span class="n">N</span> <span class="n">where</span> <span class="n">mul</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">x</span> <span class="n">y</span> <span class="bp">↦</span> <span class="o">⟨</span><span class="n">x</span><span class="bp">*</span><span class="n">y</span><span class="o">,</span> <span class="n">N.mul_mem</span> <span class="n">x.property</span> <span class="n">y.property</span><span class="o">⟩</span> <span class="n">mul_assoc</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">x</span> <span class="n">y</span> <span class="n">z</span> <span class="bp">↦</span> <span class="n">SetCoe.ext</span> <span class="o">(</span><span class="n">mul_assoc</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">M</span><span class="o">)</span> <span class="n">y</span> <span class="n">z</span><span class="o">)</span> <span class="n">one</span> <span class="o">:=</span> <span class="o">⟨</span><span class="mi">1</span><span class="o">,</span> <span class="n">N.one_mem</span><span class="o">⟩</span> <span class="n">one_mul</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">SetCoe.ext</span> <span class="o">(</span><span class="n">one_mul</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">M</span><span class="o">))</span> <span class="n">mul_one</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">SetCoe.ext</span> <span class="o">(</span><span class="n">mul_one</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">M</span><span class="o">))</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span><span class="w"> </span><span class="n">SubMonoid₁Monoid</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submonoid₁</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monoid</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">⟨</span><span class="n">x</span><span class="bp">*</span><span class="n">y</span><span class="o">,</span><span class="w"> </span><span class="n">N.mul_mem</span><span class="w"> </span><span class="n">x.property</span><span class="w"> </span><span class="n">y.property</span><span class="o">⟩</span> <span class="w"> </span><span class="n">mul_assoc</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">SetCoe.ext</span><span class="w"> </span><span class="o">(</span><span class="n">mul_assoc</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="o">)</span> <span class="w"> </span><span class="n">one</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">⟨</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="n">N.one_mem</span><span class="o">⟩</span> <span class="w"> </span><span class="n">one_mul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">SetCoe.ext</span><span class="w"> </span><span class="o">(</span><span class="n">one_mul</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="o">))</span> <span class="w"> </span><span class="n">mul_one</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">SetCoe.ext</span><span class="w"> </span><span class="o">(</span><span class="n">mul_one</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="o">))</span> </pre></div> </div> <p>Note that, in the above instance, instead of using the coercion to <code class="docutils literal notranslate"><span class="pre">M</span></code> and calling the <code class="docutils literal notranslate"><span class="pre">property</span></code> field, we could have used destructuring binders as follows.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">(</span><span class="n">N</span> <span class="o">:</span> <span class="n">Submonoid₁</span> <span class="n">M</span><span class="o">)</span> <span class="o">:</span> <span class="n">Monoid</span> <span class="n">N</span> <span class="n">where</span> <span class="n">mul</span> <span class="o">:=</span> <span class="k">fun</span> <span class="o">⟨</span><span class="n">x</span><span class="o">,</span> <span class="n">hx</span><span class="o">⟩</span> <span class="o">⟨</span><span class="n">y</span><span class="o">,</span> <span class="n">hy</span><span class="o">⟩</span> <span class="bp">↦</span> <span class="o">⟨</span><span class="n">x</span><span class="bp">*</span><span class="n">y</span><span class="o">,</span> <span class="n">N.mul_mem</span> <span class="n">hx</span> <span class="n">hy</span><span class="o">⟩</span> <span class="n">mul_assoc</span> <span class="o">:=</span> <span class="k">fun</span> <span class="o">⟨</span><span class="n">x</span><span class="o">,</span> <span class="n">_</span><span class="o">⟩</span> <span class="o">⟨</span><span class="n">y</span><span class="o">,</span> <span class="n">_</span><span class="o">⟩</span> <span class="o">⟨</span><span class="n">z</span><span class="o">,</span> <span class="n">_</span><span class="o">⟩</span> <span class="bp">↦</span> <span class="n">SetCoe.ext</span> <span class="o">(</span><span class="n">mul_assoc</span> <span class="n">x</span> <span class="n">y</span> <span class="n">z</span><span class="o">)</span> <span class="n">one</span> <span class="o">:=</span> <span class="o">⟨</span><span class="mi">1</span><span class="o">,</span> <span class="n">N.one_mem</span><span class="o">⟩</span> <span class="n">one_mul</span> <span class="o">:=</span> <span class="k">fun</span> <span class="o">⟨</span><span class="n">x</span><span class="o">,</span> <span class="n">_</span><span class="o">⟩</span> <span class="bp">↦</span> <span class="n">SetCoe.ext</span> <span class="o">(</span><span class="n">one_mul</span> <span class="n">x</span><span class="o">)</span> <span class="n">mul_one</span> <span class="o">:=</span> <span class="k">fun</span> <span class="o">⟨</span><span class="n">x</span><span class="o">,</span> <span class="n">_</span><span class="o">⟩</span> <span class="bp">↦</span> <span class="n">SetCoe.ext</span> <span class="o">(</span><span class="n">mul_one</span> <span class="n">x</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submonoid₁</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monoid</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="o">⟨</span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">hx</span><span class="o">⟩</span><span class="w"> </span><span class="o">⟨</span><span class="n">y</span><span class="o">,</span><span class="w"> </span><span class="n">hy</span><span class="o">⟩</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">⟨</span><span class="n">x</span><span class="bp">*</span><span class="n">y</span><span class="o">,</span><span class="w"> </span><span class="n">N.mul_mem</span><span class="w"> </span><span class="n">hx</span><span class="w"> </span><span class="n">hy</span><span class="o">⟩</span> <span class="w"> </span><span class="n">mul_assoc</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="o">⟨</span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">_</span><span class="o">⟩</span><span class="w"> </span><span class="o">⟨</span><span class="n">y</span><span class="o">,</span><span class="w"> </span><span class="n">_</span><span class="o">⟩</span><span class="w"> </span><span class="o">⟨</span><span class="n">z</span><span class="o">,</span><span class="w"> </span><span class="n">_</span><span class="o">⟩</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">SetCoe.ext</span><span class="w"> </span><span class="o">(</span><span class="n">mul_assoc</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="o">)</span> <span class="w"> </span><span class="n">one</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">⟨</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="n">N.one_mem</span><span class="o">⟩</span> <span class="w"> </span><span class="n">one_mul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="o">⟨</span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">_</span><span class="o">⟩</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">SetCoe.ext</span><span class="w"> </span><span class="o">(</span><span class="n">one_mul</span><span class="w"> </span><span class="n">x</span><span class="o">)</span> <span class="w"> </span><span class="n">mul_one</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="o">⟨</span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">_</span><span class="o">⟩</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">SetCoe.ext</span><span class="w"> </span><span class="o">(</span><span class="n">mul_one</span><span class="w"> </span><span class="n">x</span><span class="o">)</span> </pre></div> </div> <p>In order to apply lemmas about submonoids to subgroups or subrings, we need a class, just like for morphisms. Note this class take a <code class="docutils literal notranslate"><span class="pre">SetLike</span></code> instance as a parameter so it does not need a carrier field and can use the membership notation in its fields.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span> <span class="n">SubmonoidClass₁</span> <span class="o">(</span><span class="n">S</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">(</span><span class="n">M</span> <span class="o">:</span> <span class="kt">Type</span><span class="o">)</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">[</span><span class="n">SetLike</span> <span class="n">S</span> <span class="n">M</span><span class="o">]</span> <span class="o">:</span> <span class="kt">Prop</span> <span class="n">where</span> <span class="n">mul_mem</span> <span class="o">:</span> <span class="bp">∀</span> <span class="o">(</span><span class="n">s</span> <span class="o">:</span> <span class="n">S</span><span class="o">)</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">M</span><span class="o">},</span> <span class="n">a</span> <span class="bp">∈</span> <span class="n">s</span> <span class="bp">→</span> <span class="n">b</span> <span class="bp">∈</span> <span class="n">s</span> <span class="bp">→</span> <span class="n">a</span> <span class="bp">*</span> <span class="n">b</span> <span class="bp">∈</span> <span class="n">s</span> <span class="n">one_mem</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">s</span> <span class="o">:</span> <span class="n">S</span><span class="o">,</span> <span class="mi">1</span> <span class="bp">∈</span> <span class="n">s</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">class</span><span class="w"> </span><span class="n">SubmonoidClass₁</span><span class="w"> </span><span class="o">(</span><span class="n">S</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">M</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">SetLike</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Prop</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">mul_mem</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">S</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="o">},</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span> <span class="w"> </span><span class="n">one_mem</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">S</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span> <span class="kd">instance</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">:</span> <span class="n">SubmonoidClass₁</span> <span class="o">(</span><span class="n">Submonoid₁</span> <span class="n">M</span><span class="o">)</span> <span class="n">M</span> <span class="n">where</span> <span class="n">mul_mem</span> <span class="o">:=</span> <span class="n">Submonoid₁.mul_mem</span> <span class="n">one_mem</span> <span class="o">:=</span> <span class="n">Submonoid₁.one_mem</span> <span class="kd">instance</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">SubmonoidClass₁</span><span class="w"> </span><span class="o">(</span><span class="n">Submonoid₁</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">mul_mem</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Submonoid₁.mul_mem</span> <span class="w"> </span><span class="n">one_mem</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Submonoid₁.one_mem</span> </pre></div> </div> <p>As an exercise you should define a <code class="docutils literal notranslate"><span class="pre">Subgroup₁</span></code> structure, endow it with a <code class="docutils literal notranslate"><span class="pre">SetLike</span></code> instance
-
@@ -918,15 +919,15 @@ <p>Another very important thing to know about subobjects of a given algebraic object in Mathlibalways form a complete lattice, and this structure is used a lot. For instance you may look for the lemma saying that an intersection of submonoids is a submonoid. But this won’t be a lemma, this will be an infimum construction. Let us do the case of two submonoids.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">:</span> <span class="n">Inf</span> <span class="o">(</span><span class="n">Submonoid₁</span> <span class="n">M</span><span class="o">)</span> <span class="o">:=</span> <span class="o">⟨</span><span class="k">fun</span> <span class="n">S₁</span> <span class="n">S₂</span> <span class="bp">↦</span> <span class="o">{</span> <span class="n">carrier</span> <span class="o">:=</span> <span class="n">S₁</span> <span class="bp">∩</span> <span class="n">S₂</span> <span class="n">one_mem</span> <span class="o">:=</span> <span class="o">⟨</span><span class="n">S₁.one_mem</span><span class="o">,</span> <span class="n">S₂.one_mem</span><span class="o">⟩</span> <span class="n">mul_mem</span> <span class="o">:=</span> <span class="k">fun</span> <span class="o">⟨</span><span class="n">hx</span><span class="o">,</span> <span class="n">hx'</span><span class="o">⟩</span> <span class="o">⟨</span><span class="n">hy</span><span class="o">,</span> <span class="n">hy'</span><span class="o">⟩</span> <span class="bp">↦</span> <span class="o">⟨</span><span class="n">S₁.mul_mem</span> <span class="n">hx</span> <span class="n">hy</span><span class="o">,</span> <span class="n">S₂.mul_mem</span> <span class="n">hx'</span> <span class="n">hy'</span><span class="o">⟩</span> <span class="o">}⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">instance</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Inf</span><span class="w"> </span><span class="o">(</span><span class="n">Submonoid₁</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">⟨</span><span class="k">fun</span><span class="w"> </span><span class="n">S₁</span><span class="w"> </span><span class="n">S₂</span><span class="w"> </span><span class="bp">↦</span> <span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">carrier</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">S₁</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">S₂</span> <span class="w"> </span><span class="n">one_mem</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">⟨</span><span class="n">S₁.one_mem</span><span class="o">,</span><span class="w"> </span><span class="n">S₂.one_mem</span><span class="o">⟩</span> <span class="w"> </span><span class="n">mul_mem</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="o">⟨</span><span class="n">hx</span><span class="o">,</span><span class="w"> </span><span class="n">hx'</span><span class="o">⟩</span><span class="w"> </span><span class="o">⟨</span><span class="n">hy</span><span class="o">,</span><span class="w"> </span><span class="n">hy'</span><span class="o">⟩</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">⟨</span><span class="n">S₁.mul_mem</span><span class="w"> </span><span class="n">hx</span><span class="w"> </span><span class="n">hy</span><span class="o">,</span><span class="w"> </span><span class="n">S₂.mul_mem</span><span class="w"> </span><span class="n">hx'</span><span class="w"> </span><span class="n">hy'</span><span class="o">⟩</span><span class="w"> </span><span class="o">}⟩</span> </pre></div> </div> <p>This allows to get the intersections of two submonoids as a submonoid.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">(</span><span class="n">N</span> <span class="n">P</span> <span class="o">:</span> <span class="n">Submonoid₁</span> <span class="n">M</span><span class="o">)</span> <span class="o">:</span> <span class="n">Submonoid₁</span> <span class="n">M</span> <span class="o">:=</span> <span class="n">N</span> <span class="bp">⊓</span> <span class="n">P</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">N</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submonoid₁</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submonoid₁</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">P</span> </pre></div> </div> <p>You may think it’s a shame that we had to use the inf symbol <code class="docutils literal notranslate"><span class="pre">⊓</span></code> in the above example instead
-
@@ -948,31 +949,31 @@ <p>As an example, we will build the quotient of a commutative monoid by a submonoid, leave proofsto you. In the last example, you can use <code class="docutils literal notranslate"><span class="pre">Setoid.refl</span></code> but it won’t automatically pick up the relevant <code class="docutils literal notranslate"><span class="pre">Setoid</span></code> structure. You can fix this issue by providing all arguments using the <code class="docutils literal notranslate"><span class="pre">@</span></code> syntax, as in <code class="docutils literal notranslate"><span class="pre">@Setoid.refl</span> <span class="pre">M</span> <span class="pre">N.Setoid</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">Submonoid.Setoid</span> <span class="o">[</span><span class="n">CommMonoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">(</span><span class="n">N</span> <span class="o">:</span> <span class="n">Submonoid</span> <span class="n">M</span><span class="o">)</span> <span class="o">:</span> <span class="n">Setoid</span> <span class="n">M</span> <span class="n">where</span> <span class="n">r</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">x</span> <span class="n">y</span> <span class="bp">↦</span> <span class="bp">∃</span> <span class="n">w</span> <span class="bp">∈</span> <span class="n">N</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">z</span> <span class="bp">∈</span> <span class="n">N</span><span class="o">,</span> <span class="n">x</span><span class="bp">*</span><span class="n">w</span> <span class="bp">=</span> <span class="n">y</span><span class="bp">*</span><span class="n">z</span> <span class="n">iseqv</span> <span class="o">:=</span> <span class="o">{</span> <span class="n">refl</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="o">⟨</span><span class="mi">1</span><span class="o">,</span> <span class="n">N.one_mem</span><span class="o">,</span> <span class="mi">1</span><span class="o">,</span> <span class="n">N.one_mem</span><span class="o">,</span> <span class="n">rfl</span><span class="o">⟩</span> <span class="n">symm</span> <span class="o">:=</span> <span class="k">fun</span> <span class="o">⟨</span><span class="n">w</span><span class="o">,</span> <span class="n">hw</span><span class="o">,</span> <span class="n">z</span><span class="o">,</span> <span class="n">hz</span><span class="o">,</span> <span class="n">h</span><span class="o">⟩</span> <span class="bp">↦</span> <span class="o">⟨</span><span class="n">z</span><span class="o">,</span> <span class="n">hz</span><span class="o">,</span> <span class="n">w</span><span class="o">,</span> <span class="n">hw</span><span class="o">,</span> <span class="n">h.symm</span><span class="o">⟩</span> <span class="n">trans</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="o">}</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">Submonoid.Setoid</span><span class="w"> </span><span class="o">[</span><span class="n">CommMonoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submonoid</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Setoid</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="bp">*</span><span class="n">w</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">y</span><span class="bp">*</span><span class="n">z</span> <span class="w"> </span><span class="n">iseqv</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">{</span> <span class="w"> </span><span class="n">refl</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">⟨</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="n">N.one_mem</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="n">N.one_mem</span><span class="o">,</span><span class="w"> </span><span class="n">rfl</span><span class="o">⟩</span> <span class="w"> </span><span class="n">symm</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="o">⟨</span><span class="n">w</span><span class="o">,</span><span class="w"> </span><span class="n">hw</span><span class="o">,</span><span class="w"> </span><span class="n">z</span><span class="o">,</span><span class="w"> </span><span class="n">hz</span><span class="o">,</span><span class="w"> </span><span class="n">h</span><span class="o">⟩</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">⟨</span><span class="n">z</span><span class="o">,</span><span class="w"> </span><span class="n">hz</span><span class="o">,</span><span class="w"> </span><span class="n">w</span><span class="o">,</span><span class="w"> </span><span class="n">hw</span><span class="o">,</span><span class="w"> </span><span class="n">h.symm</span><span class="o">⟩</span> <span class="w"> </span><span class="n">trans</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="o">}</span> <span class="kd">instance</span> <span class="o">[</span><span class="n">CommMonoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">:</span> <span class="n">HasQuotient</span> <span class="n">M</span> <span class="o">(</span><span class="n">Submonoid</span> <span class="n">M</span><span class="o">)</span> <span class="n">where</span> <span class="n">quotient'</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">N</span> <span class="bp">↦</span> <span class="n">Quotient</span> <span class="n">N.Setoid</span> <span class="kd">instance</span><span class="w"> </span><span class="o">[</span><span class="n">CommMonoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">HasQuotient</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="o">(</span><span class="n">Submonoid</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">quotient'</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">Quotient</span><span class="w"> </span><span class="n">N.Setoid</span> <span class="kd">def</span> <span class="n">QuotientMonoid.mk</span> <span class="o">[</span><span class="n">CommMonoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">(</span><span class="n">N</span> <span class="o">:</span> <span class="n">Submonoid</span> <span class="n">M</span><span class="o">)</span> <span class="o">:</span> <span class="n">M</span> <span class="bp">→</span> <span class="n">M</span> <span class="bp">⧸</span> <span class="n">N</span> <span class="o">:=</span> <span class="n">Quotient.mk</span> <span class="n">N.Setoid</span> <span class="kd">def</span><span class="w"> </span><span class="n">QuotientMonoid.mk</span><span class="w"> </span><span class="o">[</span><span class="n">CommMonoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submonoid</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Quotient.mk</span><span class="w"> </span><span class="n">N.Setoid</span> <span class="kd">instance</span> <span class="o">[</span><span class="n">CommMonoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">(</span><span class="n">N</span> <span class="o">:</span> <span class="n">Submonoid</span> <span class="n">M</span><span class="o">)</span> <span class="o">:</span> <span class="n">Monoid</span> <span class="o">(</span><span class="n">M</span> <span class="bp">⧸</span> <span class="n">N</span><span class="o">)</span> <span class="n">where</span> <span class="n">mul</span> <span class="o">:=</span> <span class="n">Quotient.map₂'</span> <span class="o">(</span><span class="bp">·</span> <span class="bp">*</span> <span class="bp">·</span><span class="o">)</span> <span class="o">(</span><span class="kd">by</span> <span class="gr">sorry</span> <span class="o">)</span> <span class="n">mul_assoc</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="n">one</span> <span class="o">:=</span> <span class="n">QuotientMonoid.mk</span> <span class="n">N</span> <span class="mi">1</span> <span class="n">one_mul</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="n">mul_one</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">instance</span><span class="w"> </span><span class="o">[</span><span class="n">CommMonoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submonoid</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Monoid</span><span class="w"> </span><span class="o">(</span><span class="n">M</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">N</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">mul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Quotient.map₂'</span><span class="w"> </span><span class="o">(</span><span class="bp">·</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="bp">·</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="o">)</span> <span class="w"> </span><span class="n">mul_assoc</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">one</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">QuotientMonoid.mk</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="mi">1</span> <span class="w"> </span><span class="n">one_mul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">mul_one</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> </section>
-
-
-
@@ -1,3 +1,5 @@<!DOCTYPE html> <html class="writer-html5" lang="en" data-content_root="./"> <head>
-
@@ -6,18 +8,17 @@<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>8. Groups and Rings — Mathematics in Lean 0.1 documentation</title> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=80d5e7a1" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=86f27845" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" /> <link rel="stylesheet" type="text/css" href="_static/css/custom.css?v=0731ccc3" /> <link rel="shortcut icon" href="_static/favicon.ico"/> <script src="_static/jquery.js?v=8dae8fb0"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=888ff710"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> <script src="_static/jquery.js?v=5d32c60e"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=9bcbadda"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> <script src="_static/js/theme.js"></script> <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" />
-
@@ -143,9 +144,9 @@ argument (in other words, in square brackets).By default, <code class="docutils literal notranslate"><span class="pre">Monoid</span></code> uses multiplicative notation for the operation; for additive notation use <code class="docutils literal notranslate"><span class="pre">AddMonoid</span></code> instead. The commutative versions of these structures add the prefix <code class="docutils literal notranslate"><span class="pre">Comm</span></code> before <code class="docutils literal notranslate"><span class="pre">Monoid</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">M</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">M</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">*</span> <span class="mi">1</span> <span class="bp">=</span> <span class="n">x</span> <span class="o">:=</span> <span class="n">mul_one</span> <span class="n">x</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">M</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">mul_one</span><span class="w"> </span><span class="n">x</span> <span class="kd">example</span> <span class="o">{</span><span class="n">M</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">AddCommMonoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">M</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">y</span> <span class="bp">=</span> <span class="n">y</span> <span class="bp">+</span> <span class="n">x</span> <span class="o">:=</span> <span class="n">add_comm</span> <span class="n">x</span> <span class="n">y</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">M</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">AddCommMonoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">add_comm</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span> </pre></div> </div> <p>Note that although <code class="docutils literal notranslate"><span class="pre">AddMonoid</span></code> is found in the library,
-
@@ -154,19 +155,19 @@ <p>The type of morphisms between monoids <code class="docutils literal notranslate"><span class="pre">M</span></code> and <code class="docutils literal notranslate"><span class="pre">N</span></code> is called <code class="docutils literal notranslate"><span class="pre">MonoidHom</span> <span class="pre">M</span> <span class="pre">N</span></code> and written<code class="docutils literal notranslate"><span class="pre">M</span> <span class="pre">→*</span> <span class="pre">N</span></code>. Lean will automatically see such a morphism as a function from <code class="docutils literal notranslate"><span class="pre">M</span></code> to <code class="docutils literal notranslate"><span class="pre">N</span></code> when we apply it to elements of <code class="docutils literal notranslate"><span class="pre">M</span></code>. The additive version is called <code class="docutils literal notranslate"><span class="pre">AddMonoidHom</span></code> and written <code class="docutils literal notranslate"><span class="pre">M</span> <span class="pre">→+</span> <span class="pre">N</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">M</span> <span class="n">N</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">N</span><span class="o">]</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">M</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">M</span> <span class="bp">→*</span> <span class="n">N</span><span class="o">)</span> <span class="o">:</span> <span class="n">f</span> <span class="o">(</span><span class="n">x</span> <span class="bp">*</span> <span class="n">y</span><span class="o">)</span> <span class="bp">=</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">*</span> <span class="n">f</span> <span class="n">y</span> <span class="o">:=</span> <span class="n">f.map_mul</span> <span class="n">x</span> <span class="n">y</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">M</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">N</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">N</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">f.map_mul</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span> <span class="kd">example</span> <span class="o">{</span><span class="n">M</span> <span class="n">N</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">AddMonoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">[</span><span class="n">AddMonoid</span> <span class="n">N</span><span class="o">]</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">M</span> <span class="bp">→+</span> <span class="n">N</span><span class="o">)</span> <span class="o">:</span> <span class="n">f</span> <span class="mi">0</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="n">f.map_zero</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">M</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">AddMonoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">AddMonoid</span><span class="w"> </span><span class="n">N</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="bp">→+</span><span class="w"> </span><span class="n">N</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">f.map_zero</span> </pre></div> </div> <p>These morphisms are bundled maps, i.e. they package together a map and some of its properties. Remember that <a class="reference internal" href="C07_Hierarchies.html#section-hierarchies-morphisms"><span class="std std-numref">Section 7.2</span></a> explains bundled maps; here we simply note the slightly unfortunate consequence that we cannot use ordinary function composition to compose maps. Instead, we need to use <code class="docutils literal notranslate"><span class="pre">MonoidHom.comp</span></code> and <code class="docutils literal notranslate"><span class="pre">AddMonoidHom.comp</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">M</span> <span class="n">N</span> <span class="n">P</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">AddMonoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">[</span><span class="n">AddMonoid</span> <span class="n">N</span><span class="o">]</span> <span class="o">[</span><span class="n">AddMonoid</span> <span class="n">P</span><span class="o">]</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">M</span> <span class="bp">→+</span> <span class="n">N</span><span class="o">)</span> <span class="o">(</span><span class="n">g</span> <span class="o">:</span> <span class="n">N</span> <span class="bp">→+</span> <span class="n">P</span><span class="o">)</span> <span class="o">:</span> <span class="n">M</span> <span class="bp">→+</span> <span class="n">P</span> <span class="o">:=</span> <span class="n">g.comp</span> <span class="n">f</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">M</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">AddMonoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">AddMonoid</span><span class="w"> </span><span class="n">N</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">AddMonoid</span><span class="w"> </span><span class="n">P</span><span class="o">]</span> <span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="bp">→+</span><span class="w"> </span><span class="n">N</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="bp">→+</span><span class="w"> </span><span class="n">P</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="bp">→+</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">g.comp</span><span class="w"> </span><span class="n">f</span> </pre></div> </div> </section>
-
@@ -174,31 +175,31 @@ <section id="groups-and-their-morphisms"><h3><span class="section-number">8.1.2. </span>Groups and their morphisms<a class="headerlink" href="#groups-and-their-morphisms" title="Link to this heading"></a></h3> <p>We will have much more to say about groups, which are monoids with the extra property that every element has an inverse.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">*</span> <span class="n">x</span><span class="bp">⁻¹</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="n">mul_inv_cancel</span> <span class="n">x</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">x</span><span class="bp">⁻¹</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">mul_inv_cancel</span><span class="w"> </span><span class="n">x</span> </pre></div> </div> <p id="index-2">Similar to the <code class="docutils literal notranslate"><span class="pre">ring</span></code> tactic that we saw earlier, there is a <code class="docutils literal notranslate"><span class="pre">group</span></code> tactic that proves any identity that holds in any group. (Equivalently, it proves the identities that hold in free groups.)</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="n">z</span> <span class="o">:</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">*</span> <span class="o">(</span><span class="n">y</span> <span class="bp">*</span> <span class="n">z</span><span class="o">)</span> <span class="bp">*</span> <span class="o">(</span><span class="n">x</span> <span class="bp">*</span> <span class="n">z</span><span class="o">)</span><span class="bp">⁻¹</span> <span class="bp">*</span> <span class="o">(</span><span class="n">x</span> <span class="bp">*</span> <span class="n">y</span> <span class="bp">*</span> <span class="n">x</span><span class="bp">⁻¹</span><span class="o">)</span><span class="bp">⁻¹</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">group</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">y</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">z</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">z</span><span class="o">)</span><span class="bp">⁻¹</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">x</span><span class="bp">⁻¹</span><span class="o">)</span><span class="bp">⁻¹</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">group</span> </pre></div> </div> <p id="index-3">There is also a tactic for identities in commutative additive groups called <code class="docutils literal notranslate"><span class="pre">abel</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">AddCommGroup</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="n">z</span> <span class="o">:</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="n">z</span> <span class="bp">+</span> <span class="n">x</span> <span class="bp">+</span> <span class="o">(</span><span class="n">y</span> <span class="bp">-</span> <span class="n">z</span> <span class="bp">-</span> <span class="n">x</span><span class="o">)</span> <span class="bp">=</span> <span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">abel</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">AddCommGroup</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="o">(</span><span class="n">y</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">abel</span> </pre></div> </div> <p>Interestingly, a group morphism is nothing more than a monoid morphism between groups. So we can copy and paste one of our earlier examples, replacing <code class="docutils literal notranslate"><span class="pre">Monoid</span></code> with <code class="docutils literal notranslate"><span class="pre">Group</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="n">H</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">Group</span> <span class="n">H</span><span class="o">]</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">G</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→*</span> <span class="n">H</span><span class="o">)</span> <span class="o">:</span> <span class="n">f</span> <span class="o">(</span><span class="n">x</span> <span class="bp">*</span> <span class="n">y</span><span class="o">)</span> <span class="bp">=</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">*</span> <span class="n">f</span> <span class="n">y</span> <span class="o">:=</span> <span class="n">f.map_mul</span> <span class="n">x</span> <span class="n">y</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">H</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">f.map_mul</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span> </pre></div> </div> <p>Of course we do get some new properties, such as this one:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="n">H</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">Group</span> <span class="n">H</span><span class="o">]</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">G</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→*</span> <span class="n">H</span><span class="o">)</span> <span class="o">:</span> <span class="n">f</span> <span class="o">(</span><span class="n">x</span><span class="bp">⁻¹</span><span class="o">)</span> <span class="bp">=</span> <span class="o">(</span><span class="n">f</span> <span class="n">x</span><span class="o">)</span><span class="bp">⁻¹</span> <span class="o">:=</span> <span class="n">f.map_inv</span> <span class="n">x</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">H</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="bp">⁻¹</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="bp">⁻¹</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">f.map_inv</span><span class="w"> </span><span class="n">x</span> </pre></div> </div> <p>You may be worried that constructing group morphisms will require us to do unnecessary work since
-
@@ -206,9 +207,9 @@ the definition of monoid morphism enforces that neutral elements are sent to neutral elementswhile this is automatic in the case of group morphisms. In practice the extra work is not hard, but, to avoid it, there is a function building a group morphism from a function between groups that is compatible with the composition laws.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="n">H</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">Group</span> <span class="n">H</span><span class="o">]</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→</span> <span class="n">H</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="n">y</span><span class="o">,</span> <span class="n">f</span> <span class="o">(</span><span class="n">x</span> <span class="bp">*</span> <span class="n">y</span><span class="o">)</span> <span class="bp">=</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">*</span> <span class="n">f</span> <span class="n">y</span><span class="o">)</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→*</span> <span class="n">H</span> <span class="o">:=</span> <span class="n">MonoidHom.mk'</span> <span class="n">f</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">H</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">MonoidHom.mk'</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>There is also a type <code class="docutils literal notranslate"><span class="pre">MulEquiv</span></code> of group (or monoid) isomorphisms denoted by <code class="docutils literal notranslate"><span class="pre">≃*</span></code> (and
-
@@ -219,17 +220,17 @@ the identity isomorphism of <code class="docutils literal notranslate"><span class="pre">G</span></code> is <code class="docutils literal notranslate"><span class="pre">M̀ulEquiv.refl</span> <span class="pre">G</span></code>.Using anonymous projector notation, the first two can be written <code class="docutils literal notranslate"><span class="pre">f.symm</span></code> and <code class="docutils literal notranslate"><span class="pre">f.trans</span> <span class="pre">g</span></code> respectively. Elements of this type are automatically coerced to morphisms and functions when necessary.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="n">H</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">Group</span> <span class="n">H</span><span class="o">]</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">≃*</span> <span class="n">H</span><span class="o">)</span> <span class="o">:</span> <span class="n">f.trans</span> <span class="n">f.symm</span> <span class="bp">=</span> <span class="n">MulEquiv.refl</span> <span class="n">G</span> <span class="o">:=</span> <span class="n">f.self_trans_symm</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">H</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">≃*</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">f.trans</span><span class="w"> </span><span class="n">f.symm</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">MulEquiv.refl</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">f.self_trans_symm</span> </pre></div> </div> <p>One can use <code class="docutils literal notranslate"><span class="pre">MulEquiv.ofBijective</span></code> to build an isomorphism from a bijective morphism. Doing so makes the inverse function noncomputable.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">noncomputable</span> <span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="n">H</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">Group</span> <span class="n">H</span><span class="o">]</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→*</span> <span class="n">H</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">Function.Bijective</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">≃*</span> <span class="n">H</span> <span class="o">:=</span> <span class="n">MulEquiv.ofBijective</span> <span class="n">f</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">noncomputable</span><span class="w"> </span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">H</span><span class="o">]</span> <span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Function.Bijective</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">≃*</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">MulEquiv.ofBijective</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> </section>
-
@@ -237,13 +238,13 @@ <section id="subgroups"><h3><span class="section-number">8.1.3. </span>Subgroups<a class="headerlink" href="#subgroups" title="Link to this heading"></a></h3> <p>Just as group morphisms are bundled, a subgroup of <code class="docutils literal notranslate"><span class="pre">G</span></code> is also a bundled structure consisting of a set in <code class="docutils literal notranslate"><span class="pre">G</span></code> with the relevant closure properties.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">H</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">)</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">G</span><span class="o">}</span> <span class="o">(</span><span class="n">hx</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">H</span><span class="o">)</span> <span class="o">(</span><span class="n">hy</span> <span class="o">:</span> <span class="n">y</span> <span class="bp">∈</span> <span class="n">H</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">*</span> <span class="n">y</span> <span class="bp">∈</span> <span class="n">H</span> <span class="o">:=</span> <span class="n">H.mul_mem</span> <span class="n">hx</span> <span class="n">hy</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hx</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hy</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">H.mul_mem</span><span class="w"> </span><span class="n">hx</span><span class="w"> </span><span class="n">hy</span> <span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">H</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">)</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">G</span><span class="o">}</span> <span class="o">(</span><span class="n">hx</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">H</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span><span class="bp">⁻¹</span> <span class="bp">∈</span> <span class="n">H</span> <span class="o">:=</span> <span class="n">H.inv_mem</span> <span class="n">hx</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hx</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">x</span><span class="bp">⁻¹</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">H.inv_mem</span><span class="w"> </span><span class="n">hx</span> </pre></div> </div> <p>In the example above, it is important to understand that <code class="docutils literal notranslate"><span class="pre">Subgroup</span> <span class="pre">G</span></code> is the type of subgroups
-
@@ -256,29 +257,29 @@ equal in the same way it is used to prove that two sets are equal.</p><p>To state and prove, for example, that <code class="docutils literal notranslate"><span class="pre">ℤ</span></code> is an additive subgroup of <code class="docutils literal notranslate"><span class="pre">ℚ</span></code>, what we really want is to construct a term of type <code class="docutils literal notranslate"><span class="pre">AddSubgroup</span> <span class="pre">ℚ</span></code> whose projection to <code class="docutils literal notranslate"><span class="pre">Set</span> <span class="pre">ℚ</span></code> is <code class="docutils literal notranslate"><span class="pre">ℤ</span></code>, or, more precisely, the image of <code class="docutils literal notranslate"><span class="pre">ℤ</span></code> in <code class="docutils literal notranslate"><span class="pre">ℚ</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">AddSubgroup</span> <span class="n">ℚ</span> <span class="n">where</span> <span class="n">carrier</span> <span class="o">:=</span> <span class="n">Set.range</span> <span class="o">((</span><span class="bp">↑</span><span class="o">)</span> <span class="o">:</span> <span class="n">ℤ</span> <span class="bp">→</span> <span class="n">ℚ</span><span class="o">)</span> <span class="n">add_mem'</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rintro</span> <span class="n">_</span> <span class="n">_</span> <span class="o">⟨</span><span class="n">n</span><span class="o">,</span> <span class="n">rfl</span><span class="o">⟩</span> <span class="o">⟨</span><span class="n">m</span><span class="o">,</span> <span class="n">rfl</span><span class="o">⟩</span> <span class="n">use</span> <span class="n">n</span> <span class="bp">+</span> <span class="n">m</span> <span class="n">simp</span> <span class="n">zero_mem'</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">use</span> <span class="mi">0</span> <span class="n">simp</span> <span class="n">neg_mem'</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rintro</span> <span class="n">_</span> <span class="o">⟨</span><span class="n">n</span><span class="o">,</span> <span class="n">rfl</span><span class="o">⟩</span> <span class="n">use</span> <span class="bp">-</span><span class="n">n</span> <span class="n">simp</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">AddSubgroup</span><span class="w"> </span><span class="n">ℚ</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">carrier</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Set.range</span><span class="w"> </span><span class="o">((</span><span class="bp">↑</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℤ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℚ</span><span class="o">)</span> <span class="w"> </span><span class="n">add_mem'</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">⟨</span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">rfl</span><span class="o">⟩</span><span class="w"> </span><span class="o">⟨</span><span class="n">m</span><span class="o">,</span><span class="w"> </span><span class="n">rfl</span><span class="o">⟩</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">m</span> <span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="n">zero_mem'</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="mi">0</span> <span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="n">neg_mem'</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">⟨</span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">rfl</span><span class="o">⟩</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="bp">-</span><span class="n">n</span> <span class="w"> </span><span class="n">simp</span> </pre></div> </div> <p>Using type classes, Mathlib knows that a subgroup of a group inherits a group structure.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">H</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="n">Group</span> <span class="n">H</span> <span class="o">:=</span> <span class="n">inferInstance</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Group</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">inferInstance</span> </pre></div> </div> <p>This example is subtle. The object <code class="docutils literal notranslate"><span class="pre">H</span></code> is not a type, but Lean automatically coerces it to a type by interpreting it as a subtype of <code class="docutils literal notranslate"><span class="pre">G</span></code>. So the above example can be restated more explicitly as:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">H</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="n">Group</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">//</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">H</span><span class="o">}</span> <span class="o">:=</span> <span class="n">inferInstance</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Group</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">//</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">H</span><span class="o">}</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">inferInstance</span> </pre></div> </div> <p>An important benefit of having a type <code class="docutils literal notranslate"><span class="pre">Subgroup</span> <span class="pre">G</span></code> instead of a predicate
-
@@ -290,8 +291,8 @@ have used the lattice operation <code class="docutils literal notranslate"><span class="pre">⊓</span></code> to construct the intersection. We can then apply arbitrarylemmas about lattices to the construction.</p> <p>Let us check that the set underlying the infimum of two subgroups is indeed, by definition, their intersection.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">H</span> <span class="n">H'</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="o">((</span><span class="n">H</span> <span class="bp">⊓</span> <span class="n">H'</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">G</span><span class="o">)</span> <span class="bp">=</span> <span class="o">(</span><span class="n">H</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">G</span><span class="o">)</span> <span class="bp">∩</span> <span class="o">(</span><span class="n">H'</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">G</span><span class="o">)</span> <span class="o">:=</span> <span class="n">rfl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">H</span><span class="w"> </span><span class="n">H'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="o">((</span><span class="n">H</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">H'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="o">(</span><span class="n">H'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">rfl</span> </pre></div> </div> <p>It may look strange to have a different notation for what amounts to the intersection of the
-
@@ -299,36 +300,36 @@ underlying sets, but the correspondence does not carry over to the supremum operation and setunion, since a union of subgroups is not, in general, a subgroup. Instead one needs to use the subgroup generated by the union, which is done using <code class="docutils literal notranslate"><span class="pre">Subgroup.closure</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">H</span> <span class="n">H'</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="o">((</span><span class="n">H</span> <span class="bp">⊔</span> <span class="n">H'</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">G</span><span class="o">)</span> <span class="bp">=</span> <span class="n">Subgroup.closure</span> <span class="o">((</span><span class="n">H</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">G</span><span class="o">)</span> <span class="bp">∪</span> <span class="o">(</span><span class="n">H'</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">G</span><span class="o">))</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">Subgroup.sup_eq_closure</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">H</span><span class="w"> </span><span class="n">H'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="o">((</span><span class="n">H</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">H'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">Subgroup.closure</span><span class="w"> </span><span class="o">((</span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="o">(</span><span class="n">H'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">G</span><span class="o">))</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">Subgroup.sup_eq_closure</span><span class="o">]</span> </pre></div> </div> <p>Another subtlety is that <code class="docutils literal notranslate"><span class="pre">G</span></code> itself does not have type <code class="docutils literal notranslate"><span class="pre">Subgroup</span> <span class="pre">G</span></code>, so we need a way to talk about <code class="docutils literal notranslate"><span class="pre">G</span></code> seen as a subgroup of <code class="docutils literal notranslate"><span class="pre">G</span></code>. This is also provided by the lattice structure: the full subgroup is the top element of this lattice.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∈</span> <span class="o">(</span><span class="bp">⊤</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">)</span> <span class="o">:=</span> <span class="n">trivial</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="o">(</span><span class="bp">⊤</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">trivial</span> </pre></div> </div> <p>Similarly the bottom element of this lattice is the subgroup whose only element is the neutral element.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∈</span> <span class="o">(</span><span class="bp">⊥</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">)</span> <span class="bp">↔</span> <span class="n">x</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="n">Subgroup.mem_bot</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="o">(</span><span class="bp">⊥</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Subgroup.mem_bot</span> </pre></div> </div> <p>As an exercise in manipulating groups and subgroups, you can define the conjugate of a subgroup by an element of the ambient group.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">conjugate</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">G</span><span class="o">)</span> <span class="o">(</span><span class="n">H</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span> <span class="n">where</span> <span class="n">carrier</span> <span class="o">:=</span> <span class="o">{</span><span class="n">a</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">|</span> <span class="bp">∃</span> <span class="n">h</span><span class="o">,</span> <span class="n">h</span> <span class="bp">∈</span> <span class="n">H</span> <span class="bp">∧</span> <span class="n">a</span> <span class="bp">=</span> <span class="n">x</span> <span class="bp">*</span> <span class="n">h</span> <span class="bp">*</span> <span class="n">x</span><span class="bp">⁻¹</span><span class="o">}</span> <span class="n">one_mem'</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">dsimp</span> <span class="gr">sorry</span> <span class="n">inv_mem'</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">dsimp</span> <span class="gr">sorry</span> <span class="n">mul_mem'</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">dsimp</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">conjugate</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">carrier</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">h</span><span class="o">,</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">x</span><span class="bp">⁻¹</span><span class="o">}</span> <span class="w"> </span><span class="n">one_mem'</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">dsimp</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">inv_mem'</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">dsimp</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">mul_mem'</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">dsimp</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Tying the previous two topics together, one can push forward and pull back subgroups using
-
@@ -336,55 +337,55 @@ group morphisms. The naming convention in Mathlib is to call those operations <code class="docutils literal notranslate"><span class="pre">map</span></code>and <code class="docutils literal notranslate"><span class="pre">comap</span></code>. These are not the common mathematical terms, but they have the advantage of being shorter than “pushforward” and “direct image.”</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="n">H</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">Group</span> <span class="n">H</span><span class="o">]</span> <span class="o">(</span><span class="n">G'</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→*</span> <span class="n">H</span><span class="o">)</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">H</span> <span class="o">:=</span> <span class="n">Subgroup.map</span> <span class="n">f</span> <span class="n">G'</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">H</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">G'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Subgroup.map</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">G'</span> <span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="n">H</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">Group</span> <span class="n">H</span><span class="o">]</span> <span class="o">(</span><span class="n">H'</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">H</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→*</span> <span class="n">H</span><span class="o">)</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span> <span class="o">:=</span> <span class="n">Subgroup.comap</span> <span class="n">f</span> <span class="n">H'</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">H</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">H'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Subgroup.comap</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">H'</span> <span class="k">#check</span> <span class="n">Subgroup.mem_map</span> <span class="k">#check</span> <span class="n">Subgroup.mem_comap</span> <span class="k">#check</span><span class="w"> </span><span class="n">Subgroup.mem_map</span> <span class="k">#check</span><span class="w"> </span><span class="n">Subgroup.mem_comap</span> </pre></div> </div> <p>In particular, the preimage of the bottom subgroup under a morphism <code class="docutils literal notranslate"><span class="pre">f</span></code> is a subgroup called the <em>kernel</em> of <code class="docutils literal notranslate"><span class="pre">f</span></code>, and the range of <code class="docutils literal notranslate"><span class="pre">f</span></code> is also a subgroup.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="n">H</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">Group</span> <span class="n">H</span><span class="o">]</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→*</span> <span class="n">H</span><span class="o">)</span> <span class="o">(</span><span class="n">g</span> <span class="o">:</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="n">g</span> <span class="bp">∈</span> <span class="n">MonoidHom.ker</span> <span class="n">f</span> <span class="bp">↔</span> <span class="n">f</span> <span class="n">g</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="n">f.mem_ker</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">H</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">MonoidHom.ker</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">f.mem_ker</span> <span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="n">H</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">Group</span> <span class="n">H</span><span class="o">]</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→*</span> <span class="n">H</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">H</span><span class="o">)</span> <span class="o">:</span> <span class="n">h</span> <span class="bp">∈</span> <span class="n">MonoidHom.range</span> <span class="n">f</span> <span class="bp">↔</span> <span class="bp">∃</span> <span class="n">g</span> <span class="o">:</span> <span class="n">G</span><span class="o">,</span> <span class="n">f</span> <span class="n">g</span> <span class="bp">=</span> <span class="n">h</span> <span class="o">:=</span> <span class="n">f.mem_range</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">H</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">MonoidHom.range</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">f.mem_range</span> </pre></div> </div> <p>As exercises in manipulating group morphisms and subgroups, let us prove some elementary properties. They are already proved in Mathlib, so do not use <code class="docutils literal notranslate"><span class="pre">exact?</span></code> too quickly if you want to benefit from these exercises.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span> <span class="n">exercises</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">G</span> <span class="n">H</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">Group</span> <span class="n">H</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span><span class="w"> </span><span class="n">exercises</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">H</span><span class="o">]</span> <span class="kn">open</span> <span class="n">Subgroup</span> <span class="kn">open</span><span class="w"> </span><span class="n">Subgroup</span> <span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→*</span> <span class="n">H</span><span class="o">)</span> <span class="o">(</span><span class="n">S</span> <span class="n">T</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">H</span><span class="o">)</span> <span class="o">(</span><span class="n">hST</span> <span class="o">:</span> <span class="n">S</span> <span class="bp">≤</span> <span class="n">T</span><span class="o">)</span> <span class="o">:</span> <span class="n">comap</span> <span class="n">φ</span> <span class="n">S</span> <span class="bp">≤</span> <span class="n">comap</span> <span class="n">φ</span> <span class="n">T</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">S</span><span class="w"> </span><span class="n">T</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hST</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">T</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">comap</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">comap</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">T</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→*</span> <span class="n">H</span><span class="o">)</span> <span class="o">(</span><span class="n">S</span> <span class="n">T</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">)</span> <span class="o">(</span><span class="n">hST</span> <span class="o">:</span> <span class="n">S</span> <span class="bp">≤</span> <span class="n">T</span><span class="o">)</span> <span class="o">:</span> <span class="n">map</span> <span class="n">φ</span> <span class="n">S</span> <span class="bp">≤</span> <span class="n">map</span> <span class="n">φ</span> <span class="n">T</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">S</span><span class="w"> </span><span class="n">T</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hST</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">T</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">map</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">map</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">T</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">K</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">K</span><span class="o">]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">K</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">K</span><span class="o">]</span> <span class="c1">-- Remember you can use the `ext` tactic to prove an equality of subgroups.</span> <span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→*</span> <span class="n">H</span><span class="o">)</span> <span class="o">(</span><span class="n">ψ</span> <span class="o">:</span> <span class="n">H</span> <span class="bp">→*</span> <span class="n">K</span><span class="o">)</span> <span class="o">(</span><span class="n">U</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">K</span><span class="o">)</span> <span class="o">:</span> <span class="n">comap</span> <span class="o">(</span><span class="n">ψ.comp</span> <span class="n">φ</span><span class="o">)</span> <span class="n">U</span> <span class="bp">=</span> <span class="n">comap</span> <span class="n">φ</span> <span class="o">(</span><span class="n">comap</span> <span class="n">ψ</span> <span class="n">U</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ψ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">U</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">comap</span><span class="w"> </span><span class="o">(</span><span class="n">ψ.comp</span><span class="w"> </span><span class="n">φ</span><span class="o">)</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">comap</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="o">(</span><span class="n">comap</span><span class="w"> </span><span class="n">ψ</span><span class="w"> </span><span class="n">U</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="c1">-- Pushing a subgroup along one homomorphism and then another is equal to</span> <span class="c1">-- pushing it forward along the composite of the homomorphisms.</span> <span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→*</span> <span class="n">H</span><span class="o">)</span> <span class="o">(</span><span class="n">ψ</span> <span class="o">:</span> <span class="n">H</span> <span class="bp">→*</span> <span class="n">K</span><span class="o">)</span> <span class="o">(</span><span class="n">S</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="n">map</span> <span class="o">(</span><span class="n">ψ.comp</span> <span class="n">φ</span><span class="o">)</span> <span class="n">S</span> <span class="bp">=</span> <span class="n">map</span> <span class="n">ψ</span> <span class="o">(</span><span class="n">S.map</span> <span class="n">φ</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ψ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">S</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">map</span><span class="w"> </span><span class="o">(</span><span class="n">ψ.comp</span><span class="w"> </span><span class="n">φ</span><span class="o">)</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">map</span><span class="w"> </span><span class="n">ψ</span><span class="w"> </span><span class="o">(</span><span class="n">S.map</span><span class="w"> </span><span class="n">φ</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">end</span> <span class="n">exercises</span> <span class="kd">end</span><span class="w"> </span><span class="n">exercises</span> </pre></div> </div> <p>Let us finish this introduction to subgroups in Mathlib with two very classical results.
-
@@ -392,32 +393,32 @@ Lagrange theorem states the cardinality of a subgroup of a finite group divides the cardinality ofthe group. Sylow’s first theorem is a famous partial converse to Lagrange’s theorem.</p> <p>While this corner of Mathlib is partly set up to allow computation, we can tell Lean to use nonconstructive logic anyway using the following <code class="docutils literal notranslate"><span class="pre">open</span> <span class="pre">scoped</span></code> command.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">scoped</span> <span class="n">Classical</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">scoped</span><span class="w"> </span><span class="n">Classical</span> <span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">G'</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="n">Nat.card</span> <span class="n">G'</span> <span class="bp">∣</span> <span class="n">Nat.card</span> <span class="n">G</span> <span class="o">:=</span> <span class="o">⟨</span><span class="n">G'.index</span><span class="o">,</span> <span class="n">mul_comm</span> <span class="n">G'.index</span> <span class="n">_</span> <span class="bp">▸</span> <span class="n">G'.index_mul_card.symm</span><span class="o">⟩</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">G'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat.card</span><span class="w"> </span><span class="n">G'</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">Nat.card</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">⟨</span><span class="n">G'.index</span><span class="o">,</span><span class="w"> </span><span class="n">mul_comm</span><span class="w"> </span><span class="n">G'.index</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">▸</span><span class="w"> </span><span class="n">G'.index_mul_card.symm</span><span class="o">⟩</span> <span class="kn">open</span> <span class="n">Subgroup</span> <span class="kn">open</span><span class="w"> </span><span class="n">Subgroup</span> <span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">Finite</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">p</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">{</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">[</span><span class="n">Fact</span> <span class="n">p.Prime</span><span class="o">]</span> <span class="o">(</span><span class="n">hdvd</span> <span class="o">:</span> <span class="n">p</span> <span class="bp">^</span> <span class="n">n</span> <span class="bp">∣</span> <span class="n">Nat.card</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">K</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">,</span> <span class="n">Nat.card</span> <span class="n">K</span> <span class="bp">=</span> <span class="n">p</span> <span class="bp">^</span> <span class="n">n</span> <span class="o">:=</span> <span class="n">Sylow.exists_subgroup_card_pow_prime</span> <span class="n">p</span> <span class="n">hdvd</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Finite</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Fact</span><span class="w"> </span><span class="n">p.Prime</span><span class="o">]</span> <span class="w"> </span><span class="o">(</span><span class="n">hdvd</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∣</span><span class="w"> </span><span class="n">Nat.card</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">,</span><span class="w"> </span><span class="n">Nat.card</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Sylow.exists_subgroup_card_pow_prime</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="n">hdvd</span> </pre></div> </div> <p>The next two exercises derive a corollary of Lagrange’s lemma. (This is also already in Mathlib, so do not use <code class="docutils literal notranslate"><span class="pre">exact?</span></code> too quickly.)</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">lemma</span> <span class="n">eq_bot_iff_card</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">{</span><span class="n">H</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">}</span> <span class="o">:</span> <span class="n">H</span> <span class="bp">=</span> <span class="bp">⊥</span> <span class="bp">↔</span> <span class="n">Nat.card</span> <span class="n">H</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="k">suffices</span> <span class="o">(</span><span class="bp">∀</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">H</span><span class="o">,</span> <span class="n">x</span> <span class="bp">=</span> <span class="mi">1</span><span class="o">)</span> <span class="bp">↔</span> <span class="bp">∃</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">H</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">a</span> <span class="bp">∈</span> <span class="n">H</span><span class="o">,</span> <span class="n">a</span> <span class="bp">=</span> <span class="n">x</span> <span class="kd">by</span> <span class="n">simpa</span> <span class="o">[</span><span class="n">eq_bot_iff_forall</span><span class="o">,</span> <span class="n">Nat.card_eq_one_iff_exists</span><span class="o">]</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">lemma</span><span class="w"> </span><span class="n">eq_bot_iff_card</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">}</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">⊥</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">Nat.card</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="k">suffices</span><span class="w"> </span><span class="o">(</span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">H</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">H</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">H</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">simpa</span><span class="w"> </span><span class="o">[</span><span class="n">eq_bot_iff_forall</span><span class="o">,</span><span class="w"> </span><span class="n">Nat.card_eq_one_iff_exists</span><span class="o">]</span> <span class="w"> </span><span class="gr">sorry</span> <span class="k">#check</span> <span class="n">card_dvd_of_le</span> <span class="k">#check</span><span class="w"> </span><span class="n">card_dvd_of_le</span> <span class="kd">lemma</span> <span class="n">inf_bot_of_coprime</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">H</span> <span class="n">K</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="o">(</span><span class="n">Nat.card</span> <span class="n">H</span><span class="o">)</span><span class="bp">.</span><span class="n">Coprime</span> <span class="o">(</span><span class="n">Nat.card</span> <span class="n">K</span><span class="o">))</span> <span class="o">:</span> <span class="n">H</span> <span class="bp">⊓</span> <span class="n">K</span> <span class="bp">=</span> <span class="bp">⊥</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">lemma</span><span class="w"> </span><span class="n">inf_bot_of_coprime</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">H</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">Nat.card</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="bp">.</span><span class="n">Coprime</span><span class="w"> </span><span class="o">(</span><span class="n">Nat.card</span><span class="w"> </span><span class="n">K</span><span class="o">))</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">⊥</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> </section>
-
@@ -429,10 +430,10 @@ For instance, given any type <code class="docutils literal notranslate"><span class="pre">X</span></code>, the group of permutations of <code class="docutils literal notranslate"><span class="pre">X</span></code> is <code class="docutils literal notranslate"><span class="pre">Equiv.Perm</span> <span class="pre">X</span></code>.In particular the symmetric group <span class="math notranslate nohighlight">\(\mathfrak{S}_n\)</span> is <code class="docutils literal notranslate"><span class="pre">Equiv.Perm</span> <span class="pre">(Fin</span> <span class="pre">n)</span></code>. One can state abstract results about this group, for instance saying that <code class="docutils literal notranslate"><span class="pre">Equiv.Perm</span> <span class="pre">X</span></code> is generated by cycles if <code class="docutils literal notranslate"><span class="pre">X</span></code> is finite.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">Equiv</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">Equiv</span> <span class="kd">example</span> <span class="o">{</span><span class="n">X</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Finite</span> <span class="n">X</span><span class="o">]</span> <span class="o">:</span> <span class="n">Subgroup.closure</span> <span class="o">{</span><span class="n">σ</span> <span class="o">:</span> <span class="n">Perm</span> <span class="n">X</span> <span class="bp">|</span> <span class="n">Perm.IsCycle</span> <span class="n">σ</span><span class="o">}</span> <span class="bp">=</span> <span class="bp">⊤</span> <span class="o">:=</span> <span class="n">Perm.closure_isCycle</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">X</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Finite</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup.closure</span><span class="w"> </span><span class="o">{</span><span class="n">σ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Perm</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">Perm.IsCycle</span><span class="w"> </span><span class="n">σ</span><span class="o">}</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">⊤</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Perm.closure_isCycle</span> </pre></div> </div> <p>One can be fully concrete and compute actual products of cycles. Below we use the <code class="docutils literal notranslate"><span class="pre">#simp</span></code> command,
-
@@ -440,20 +441,20 @@ which calls the <code class="docutils literal notranslate"><span class="pre">simp</span></code> tactic on a given expression. The notation <code class="docutils literal notranslate"><span class="pre">c[]</span></code> is used to define acyclic permutation. In the example, the result is a permutation of <code class="docutils literal notranslate"><span class="pre">ℕ</span></code>. One could use a type ascription such as <code class="docutils literal notranslate"><span class="pre">(1</span> <span class="pre">:</span> <span class="pre">Fin</span> <span class="pre">5)</span></code> on the first number appearing to make it a computation in <code class="docutils literal notranslate"><span class="pre">Perm</span> <span class="pre">(Fin</span> <span class="pre">5)</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="bp">#</span><span class="n">simp</span> <span class="o">[</span><span class="n">mul_assoc</span><span class="o">]</span> <span class="n">c</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span> <span class="mi">2</span><span class="o">,</span> <span class="mi">3</span><span class="o">]</span> <span class="bp">*</span> <span class="n">c</span><span class="o">[</span><span class="mi">2</span><span class="o">,</span> <span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="bp">#</span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">mul_assoc</span><span class="o">]</span><span class="w"> </span><span class="n">c</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="o">,</span><span class="w"> </span><span class="mi">3</span><span class="o">]</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">c</span><span class="o">[</span><span class="mi">2</span><span class="o">,</span><span class="w"> </span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="o">]</span> </pre></div> </div> <p>Another way to work with concrete groups is to use free groups and group presentations. The free group on a type <code class="docutils literal notranslate"><span class="pre">α</span></code> is <code class="docutils literal notranslate"><span class="pre">FreeGroup</span> <span class="pre">α</span></code> and the inclusion map is <code class="docutils literal notranslate"><span class="pre">FreeGroup.of</span> <span class="pre">:</span> <span class="pre">α</span> <span class="pre">→</span> <span class="pre">FreeGroup</span> <span class="pre">α</span></code>. For instance let us define a type <code class="docutils literal notranslate"><span class="pre">S</span></code> with three elements denoted by <code class="docutils literal notranslate"><span class="pre">a</span></code>, <code class="docutils literal notranslate"><span class="pre">b</span></code> and <code class="docutils literal notranslate"><span class="pre">c</span></code>, and the element <code class="docutils literal notranslate"><span class="pre">ab⁻¹</span></code> of the corresponding free group.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span> <span class="n">FreeGroup</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span><span class="w"> </span><span class="n">FreeGroup</span> <span class="kd">inductive</span> <span class="n">S</span> <span class="bp">|</span> <span class="n">a</span> <span class="bp">|</span> <span class="n">b</span> <span class="bp">|</span> <span class="n">c</span> <span class="kd">inductive</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">c</span> <span class="kn">open</span> <span class="n">S</span> <span class="kn">open</span><span class="w"> </span><span class="n">S</span> <span class="kd">def</span> <span class="n">myElement</span> <span class="o">:</span> <span class="n">FreeGroup</span> <span class="n">S</span> <span class="o">:=</span> <span class="o">(</span><span class="bp">.</span><span class="n">of</span> <span class="n">a</span><span class="o">)</span> <span class="bp">*</span> <span class="o">(</span><span class="bp">.</span><span class="n">of</span> <span class="n">b</span><span class="o">)</span><span class="bp">⁻¹</span> <span class="kd">def</span><span class="w"> </span><span class="n">myElement</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FreeGroup</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="bp">.</span><span class="n">of</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="bp">.</span><span class="n">of</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="bp">⁻¹</span> </pre></div> </div> <p>Note that we gave the expected type of the definition so that Lean knows that <code class="docutils literal notranslate"><span class="pre">.of</span></code> means
-
@@ -461,10 +462,10 @@ <code class="docutils literal notranslate"><span class="pre">FreeGroup.of</span></code>.</p><p>The universal property of free groups is embodied as the equivalence <code class="docutils literal notranslate"><span class="pre">FreeGroup.lift</span></code>. For example, let us define the group morphism from <code class="docutils literal notranslate"><span class="pre">FreeGroup</span> <span class="pre">S</span></code> to <code class="docutils literal notranslate"><span class="pre">Perm</span> <span class="pre">(Fin</span> <span class="pre">5)</span></code> that sends <code class="docutils literal notranslate"><span class="pre">a</span></code> to <code class="docutils literal notranslate"><span class="pre">c[1,</span> <span class="pre">2,</span> <span class="pre">3]</span></code>, <code class="docutils literal notranslate"><span class="pre">b</span></code> to <code class="docutils literal notranslate"><span class="pre">c[2,</span> <span class="pre">3,</span> <span class="pre">1]</span></code>, and <code class="docutils literal notranslate"><span class="pre">c</span></code> to <code class="docutils literal notranslate"><span class="pre">c[2,</span> <span class="pre">3]</span></code>,</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">myMorphism</span> <span class="o">:</span> <span class="n">FreeGroup</span> <span class="n">S</span> <span class="bp">→*</span> <span class="n">Perm</span> <span class="o">(</span><span class="n">Fin</span> <span class="mi">5</span><span class="o">)</span> <span class="o">:=</span> <span class="n">FreeGroup.lift</span> <span class="k">fun</span> <span class="bp">|</span> <span class="bp">.</span><span class="n">a</span> <span class="bp">=></span> <span class="n">c</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span> <span class="mi">2</span><span class="o">,</span> <span class="mi">3</span><span class="o">]</span> <span class="bp">|</span> <span class="bp">.</span><span class="n">b</span> <span class="bp">=></span> <span class="n">c</span><span class="o">[</span><span class="mi">2</span><span class="o">,</span> <span class="mi">3</span><span class="o">,</span> <span class="mi">1</span><span class="o">]</span> <span class="bp">|</span> <span class="bp">.</span><span class="n">c</span> <span class="bp">=></span> <span class="n">c</span><span class="o">[</span><span class="mi">2</span><span class="o">,</span> <span class="mi">3</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">myMorphism</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FreeGroup</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">Perm</span><span class="w"> </span><span class="o">(</span><span class="n">Fin</span><span class="w"> </span><span class="mi">5</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">FreeGroup.lift</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="bp">.</span><span class="n">a</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="n">c</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="o">,</span><span class="w"> </span><span class="mi">3</span><span class="o">]</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="bp">.</span><span class="n">b</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="n">c</span><span class="o">[</span><span class="mi">2</span><span class="o">,</span><span class="w"> </span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span><span class="o">]</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="bp">.</span><span class="n">c</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="n">c</span><span class="o">[</span><span class="mi">2</span><span class="o">,</span><span class="w"> </span><span class="mi">3</span><span class="o">]</span> </pre></div> </div> <p>As a last concrete example, let us see how to define a group generated by a single element whose
-
@@ -476,25 +477,25 @@ i.e. a set of elements of some free group, and returns a group that is this free group quotientedby a normal subgroup generated by relations. (We will see how to handle more general quotients in <a class="reference internal" href="#quotient-groups"><span class="std std-numref">Section 8.1.6</span></a>.) Since we somehow hide this behind a definition, we use <code class="docutils literal notranslate"><span class="pre">deriving</span> <span class="pre">Group</span></code> to force creation of a group instance on <code class="docutils literal notranslate"><span class="pre">myGroup</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">myGroup</span> <span class="o">:=</span> <span class="n">PresentedGroup</span> <span class="o">{</span><span class="bp">.</span><span class="n">of</span> <span class="o">()</span> <span class="bp">^</span> <span class="mi">3</span><span class="o">}</span> <span class="n">deriving</span> <span class="n">Group</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">myGroup</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">PresentedGroup</span><span class="w"> </span><span class="o">{</span><span class="bp">.</span><span class="n">of</span><span class="w"> </span><span class="o">()</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">3</span><span class="o">}</span><span class="w"> </span><span class="n">deriving</span><span class="w"> </span><span class="n">Group</span> </pre></div> </div> <p>The universal property of presented groups ensures that morphisms out of this group can be built from functions that send the relations to the neutral element of the target group. So we need such a function and a proof that the condition holds. Then we can feed this proof to <code class="docutils literal notranslate"><span class="pre">PresentedGroup.toGroup</span></code> to get the desired group morphism.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">myMap</span> <span class="o">:</span> <span class="n">Unit</span> <span class="bp">→</span> <span class="n">Perm</span> <span class="o">(</span><span class="n">Fin</span> <span class="mi">5</span><span class="o">)</span> <span class="bp">|</span> <span class="o">()</span> <span class="bp">=></span> <span class="n">c</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span> <span class="mi">2</span><span class="o">,</span> <span class="mi">3</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">myMap</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Unit</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Perm</span><span class="w"> </span><span class="o">(</span><span class="n">Fin</span><span class="w"> </span><span class="mi">5</span><span class="o">)</span> <span class="bp">|</span><span class="w"> </span><span class="o">()</span><span class="w"> </span><span class="bp">=></span><span class="w"> </span><span class="n">c</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="o">,</span><span class="w"> </span><span class="mi">3</span><span class="o">]</span> <span class="kd">lemma</span> <span class="n">compat_myMap</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">r</span> <span class="bp">∈</span> <span class="o">({</span><span class="bp">.</span><span class="n">of</span> <span class="o">()</span> <span class="bp">^</span> <span class="mi">3</span><span class="o">}</span> <span class="o">:</span> <span class="n">Set</span> <span class="o">(</span><span class="n">FreeGroup</span> <span class="n">Unit</span><span class="o">)),</span> <span class="n">FreeGroup.lift</span> <span class="n">myMap</span> <span class="n">r</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rintro</span> <span class="n">_</span> <span class="n">rfl</span> <span class="n">simp</span> <span class="n">decide</span> <span class="kd">lemma</span><span class="w"> </span><span class="n">compat_myMap</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="o">({</span><span class="bp">.</span><span class="n">of</span><span class="w"> </span><span class="o">()</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">3</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="o">(</span><span class="n">FreeGroup</span><span class="w"> </span><span class="n">Unit</span><span class="o">)),</span><span class="w"> </span><span class="n">FreeGroup.lift</span><span class="w"> </span><span class="n">myMap</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">rfl</span> <span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="n">decide</span> <span class="kd">def</span> <span class="n">myNewMorphism</span> <span class="o">:</span> <span class="n">myGroup</span> <span class="bp">→*</span> <span class="n">Perm</span> <span class="o">(</span><span class="n">Fin</span> <span class="mi">5</span><span class="o">)</span> <span class="o">:=</span> <span class="n">PresentedGroup.toGroup</span> <span class="n">compat_myMap</span> <span class="kd">def</span><span class="w"> </span><span class="n">myNewMorphism</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">myGroup</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">Perm</span><span class="w"> </span><span class="o">(</span><span class="n">Fin</span><span class="w"> </span><span class="mi">5</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">PresentedGroup.toGroup</span><span class="w"> </span><span class="n">compat_myMap</span> <span class="kd">end</span> <span class="n">FreeGroup</span> <span class="kd">end</span><span class="w"> </span><span class="n">FreeGroup</span> </pre></div> </div> </section>
-
@@ -511,31 +512,31 @@ requires some contortions, such as defining type synonyms, each of which carries differenttype class instances.</p> <p>This allows us in particular to use <code class="docutils literal notranslate"><span class="pre">g</span> <span class="pre">•</span> <span class="pre">x</span></code> to denote the action of a group element <code class="docutils literal notranslate"><span class="pre">g</span></code> on a point <code class="docutils literal notranslate"><span class="pre">x</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">noncomputable</span> <span class="kn">section</span> <span class="n">GroupActions</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">noncomputable</span><span class="w"> </span><span class="kn">section</span><span class="w"> </span><span class="n">GroupActions</span> <span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="n">X</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">MulAction</span> <span class="n">G</span> <span class="n">X</span><span class="o">]</span> <span class="o">(</span><span class="n">g</span> <span class="n">g'</span><span class="o">:</span> <span class="n">G</span><span class="o">)</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">X</span><span class="o">)</span> <span class="o">:</span> <span class="n">g</span> <span class="bp">•</span> <span class="o">(</span><span class="n">g'</span> <span class="bp">•</span> <span class="n">x</span><span class="o">)</span> <span class="bp">=</span> <span class="o">(</span><span class="n">g</span> <span class="bp">*</span> <span class="n">g'</span><span class="o">)</span> <span class="bp">•</span> <span class="n">x</span> <span class="o">:=</span> <span class="o">(</span><span class="n">mul_smul</span> <span class="n">g</span> <span class="n">g'</span> <span class="n">x</span><span class="o">)</span><span class="bp">.</span><span class="n">symm</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">MulAction</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="n">g'</span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="o">(</span><span class="n">g'</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g'</span><span class="o">)</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">(</span><span class="n">mul_smul</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">g'</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="bp">.</span><span class="n">symm</span> </pre></div> </div> <p>There is also a version for additive group called <code class="docutils literal notranslate"><span class="pre">AddAction</span></code>, where the action is denoted by <code class="docutils literal notranslate"><span class="pre">+ᵥ</span></code>. This is used for instance in the definition of affine spaces.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="n">X</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">AddGroup</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">AddAction</span> <span class="n">G</span> <span class="n">X</span><span class="o">]</span> <span class="o">(</span><span class="n">g</span> <span class="n">g'</span> <span class="o">:</span> <span class="n">G</span><span class="o">)</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">X</span><span class="o">)</span> <span class="o">:</span> <span class="n">g</span> <span class="bp">+ᵥ</span> <span class="o">(</span><span class="n">g'</span> <span class="bp">+ᵥ</span> <span class="n">x</span><span class="o">)</span> <span class="bp">=</span> <span class="o">(</span><span class="n">g</span> <span class="bp">+</span> <span class="n">g'</span><span class="o">)</span> <span class="bp">+ᵥ</span> <span class="n">x</span> <span class="o">:=</span> <span class="o">(</span><span class="n">add_vadd</span> <span class="n">g</span> <span class="n">g'</span> <span class="n">x</span><span class="o">)</span><span class="bp">.</span><span class="n">symm</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">AddGroup</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">AddAction</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="n">g'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">+ᵥ</span><span class="w"> </span><span class="o">(</span><span class="n">g'</span><span class="w"> </span><span class="bp">+ᵥ</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g'</span><span class="o">)</span><span class="w"> </span><span class="bp">+ᵥ</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">(</span><span class="n">add_vadd</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">g'</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="bp">.</span><span class="n">symm</span> </pre></div> </div> <p>The underlying group morphism is called <code class="docutils literal notranslate"><span class="pre">MulAction.toPermHom</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">MulAction</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">MulAction</span> <span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="n">X</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">MulAction</span> <span class="n">G</span> <span class="n">X</span><span class="o">]</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→*</span> <span class="n">Equiv.Perm</span> <span class="n">X</span> <span class="o">:=</span> <span class="n">toPermHom</span> <span class="n">G</span> <span class="n">X</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">MulAction</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">Equiv.Perm</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">toPermHom</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">X</span> </pre></div> </div> <p>As an illustration let us see how to define the Cayley isomorphism embedding of any group <code class="docutils literal notranslate"><span class="pre">G</span></code> into a permutation group, namely <code class="docutils literal notranslate"><span class="pre">Perm</span> <span class="pre">G</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">CayleyIsoMorphism</span> <span class="o">(</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">)</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">≃*</span> <span class="o">(</span><span class="n">toPermHom</span> <span class="n">G</span> <span class="n">G</span><span class="o">)</span><span class="bp">.</span><span class="n">range</span> <span class="o">:=</span> <span class="n">Equiv.Perm.subgroupOfMulAction</span> <span class="n">G</span> <span class="n">G</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">CayleyIsoMorphism</span><span class="w"> </span><span class="o">(</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">≃*</span><span class="w"> </span><span class="o">(</span><span class="n">toPermHom</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="bp">.</span><span class="n">range</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Equiv.Perm.subgroupOfMulAction</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">G</span> </pre></div> </div> <p>Note that nothing before the above definition required having a group rather than a monoid (or any
-
@@ -543,7 +544,7 @@ type endowed with a multiplication operation really).</p><p>The group condition really enters the picture when we will want to partition <code class="docutils literal notranslate"><span class="pre">X</span></code> into orbits. The corresponding equivalence relation on <code class="docutils literal notranslate"><span class="pre">X</span></code> is called <code class="docutils literal notranslate"><span class="pre">MulAction.orbitRel</span></code>. It is not declared as a global instance.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="n">X</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">MulAction</span> <span class="n">G</span> <span class="n">X</span><span class="o">]</span> <span class="o">:</span> <span class="n">Setoid</span> <span class="n">X</span> <span class="o">:=</span> <span class="n">orbitRel</span> <span class="n">G</span> <span class="n">X</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">MulAction</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Setoid</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">orbitRel</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">X</span> </pre></div> </div> <p>Using this we can state that <code class="docutils literal notranslate"><span class="pre">X</span></code> is partitioned into orbits under the action of <code class="docutils literal notranslate"><span class="pre">G</span></code>.
-
@@ -552,9 +553,9 @@ <code class="docutils literal notranslate"><span class="pre">(ω</span> <span class="pre">:</span> <span class="pre">orbitRel.Quotient</span> <span class="pre">G</span> <span class="pre">X)</span> <span class="pre">×</span> <span class="pre">(orbit</span> <span class="pre">G</span> <span class="pre">(Quotient.out'</span> <span class="pre">ω))</span></code>where <code class="docutils literal notranslate"><span class="pre">Quotient.out'</span> <span class="pre">ω</span></code> simply chooses an element that projects to <code class="docutils literal notranslate"><span class="pre">ω</span></code>. Recall that elements of this dependent product are pairs <code class="docutils literal notranslate"><span class="pre">⟨ω,</span> <span class="pre">x⟩</span></code> where the type <code class="docutils literal notranslate"><span class="pre">orbit</span> <span class="pre">G</span> <span class="pre">(Quotient.out'</span> <span class="pre">ω)</span></code> of <code class="docutils literal notranslate"><span class="pre">x</span></code> depends on <code class="docutils literal notranslate"><span class="pre">ω</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="n">X</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">MulAction</span> <span class="n">G</span> <span class="n">X</span><span class="o">]</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">≃</span> <span class="o">(</span><span class="n">ω</span> <span class="o">:</span> <span class="n">orbitRel.Quotient</span> <span class="n">G</span> <span class="n">X</span><span class="o">)</span> <span class="bp">×</span> <span class="o">(</span><span class="n">orbit</span> <span class="n">G</span> <span class="o">(</span><span class="n">Quotient.out'</span> <span class="n">ω</span><span class="o">))</span> <span class="o">:=</span> <span class="n">MulAction.selfEquivSigmaOrbits</span> <span class="n">G</span> <span class="n">X</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">MulAction</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">≃</span><span class="w"> </span><span class="o">(</span><span class="n">ω</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">orbitRel.Quotient</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="o">(</span><span class="n">orbit</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="o">(</span><span class="n">Quotient.out'</span><span class="w"> </span><span class="n">ω</span><span class="o">))</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">MulAction.selfEquivSigmaOrbits</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">X</span> </pre></div> </div> <p>In particular, when X is finite, this can be combined with <code class="docutils literal notranslate"><span class="pre">Fintype.card_congr</span></code> and
-
@@ -564,35 +565,35 @@ Furthermore, the orbits are in bijection with the quotient of <code class="docutils literal notranslate"><span class="pre">G</span></code> under the action of thestabilizers by left translation. This action of a subgroup by left-translation is used to define quotients of a group by a subgroup with notation <cite>/</cite> so we can use the following concise statement.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="n">X</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">MulAction</span> <span class="n">G</span> <span class="n">X</span><span class="o">]</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">X</span><span class="o">)</span> <span class="o">:</span> <span class="n">orbit</span> <span class="n">G</span> <span class="n">x</span> <span class="bp">≃</span> <span class="n">G</span> <span class="bp">⧸</span> <span class="n">stabilizer</span> <span class="n">G</span> <span class="n">x</span> <span class="o">:=</span> <span class="n">MulAction.orbitEquivQuotientStabilizer</span> <span class="n">G</span> <span class="n">x</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">MulAction</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">orbit</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≃</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">stabilizer</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">MulAction.orbitEquivQuotientStabilizer</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">x</span> </pre></div> </div> <p>An important special case of combining the above two results is when <code class="docutils literal notranslate"><span class="pre">X</span></code> is a group <code class="docutils literal notranslate"><span class="pre">G</span></code> equipped with the action of a subgroup <code class="docutils literal notranslate"><span class="pre">H</span></code> by translation. In this case all stabilizers are trivial so every orbit is in bijection with <code class="docutils literal notranslate"><span class="pre">H</span></code> and we get:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">H</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">≃</span> <span class="o">(</span><span class="n">G</span> <span class="bp">⧸</span> <span class="n">H</span><span class="o">)</span> <span class="bp">×</span> <span class="n">H</span> <span class="o">:=</span> <span class="n">groupEquivQuotientProdSubgroup</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">≃</span><span class="w"> </span><span class="o">(</span><span class="n">G</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">groupEquivQuotientProdSubgroup</span> </pre></div> </div> <p>This is the conceptual variant of the version of Lagrange theorem that we saw above. Note this version makes no finiteness assumption.</p> <p>As an exercise for this section, let us build the action of a group on its subgroup by conjugation, using our definition of <code class="docutils literal notranslate"><span class="pre">conjugate</span></code> from a previous exercise.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span> <span class="kd">lemma</span> <span class="n">conjugate_one</span> <span class="o">(</span><span class="n">H</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="n">conjugate</span> <span class="mi">1</span> <span class="n">H</span> <span class="bp">=</span> <span class="n">H</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">lemma</span><span class="w"> </span><span class="n">conjugate_one</span><span class="w"> </span><span class="o">(</span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">conjugate</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">instance</span> <span class="o">:</span> <span class="n">MulAction</span> <span class="n">G</span> <span class="o">(</span><span class="n">Subgroup</span> <span class="n">G</span><span class="o">)</span> <span class="n">where</span> <span class="n">smul</span> <span class="o">:=</span> <span class="n">conjugate</span> <span class="n">one_smul</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="n">mul_smul</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">instance</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MulAction</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="o">(</span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">smul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">conjugate</span> <span class="w"> </span><span class="n">one_smul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">mul_smul</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">end</span> <span class="n">GroupActions</span> <span class="kd">end</span><span class="w"> </span><span class="n">GroupActions</span> </pre></div> </div> </section>
-
@@ -604,19 +605,19 @@ map is a group morphism if and only if <code class="docutils literal notranslate"><span class="pre">H</span></code> is a normal subgroup (and this group structure isthen unique).</p> <p>The normality assumption is a type class <code class="docutils literal notranslate"><span class="pre">Subgroup.Normal</span></code> so that type class inference can use it to derive the group structure on the quotient.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">noncomputable</span> <span class="kn">section</span> <span class="n">QuotientGroup</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">noncomputable</span><span class="w"> </span><span class="kn">section</span><span class="w"> </span><span class="n">QuotientGroup</span> <span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">H</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">)</span> <span class="o">[</span><span class="n">H.Normal</span><span class="o">]</span> <span class="o">:</span> <span class="n">Group</span> <span class="o">(</span><span class="n">G</span> <span class="bp">⧸</span> <span class="n">H</span><span class="o">)</span> <span class="o">:=</span> <span class="n">inferInstance</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">H.Normal</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Group</span><span class="w"> </span><span class="o">(</span><span class="n">G</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">inferInstance</span> <span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">H</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">)</span> <span class="o">[</span><span class="n">H.Normal</span><span class="o">]</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→*</span> <span class="n">G</span> <span class="bp">⧸</span> <span class="n">H</span> <span class="o">:=</span> <span class="n">QuotientGroup.mk'</span> <span class="n">H</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">H.Normal</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">QuotientGroup.mk'</span><span class="w"> </span><span class="n">H</span> </pre></div> </div> <p>The universal property of quotient groups is accessed through <code class="docutils literal notranslate"><span class="pre">QuotientGroup.lift</span></code>: a group morphism <code class="docutils literal notranslate"><span class="pre">φ</span></code> descends to <code class="docutils literal notranslate"><span class="pre">G</span> <span class="pre">⧸</span> <span class="pre">N</span></code> as soon as its kernel contains <code class="docutils literal notranslate"><span class="pre">N</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">N</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">)</span> <span class="o">[</span><span class="n">N.Normal</span><span class="o">]</span> <span class="o">{</span><span class="n">M</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">M</span><span class="o">]</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→*</span> <span class="n">M</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">N</span> <span class="bp">≤</span> <span class="n">MonoidHom.ker</span> <span class="n">φ</span><span class="o">)</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">⧸</span> <span class="n">N</span> <span class="bp">→*</span> <span class="n">M</span> <span class="o">:=</span> <span class="n">QuotientGroup.lift</span> <span class="n">N</span> <span class="n">φ</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">N.Normal</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">M</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">MonoidHom.ker</span><span class="w"> </span><span class="n">φ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">QuotientGroup.lift</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>The fact that the target group is called <code class="docutils literal notranslate"><span class="pre">M</span></code> is the above snippet is a clue that having a
-
@@ -624,9 +625,9 @@ monoid structure on <code class="docutils literal notranslate"><span class="pre">M</span></code> would be enough.</p><p>An important special case is when <code class="docutils literal notranslate"><span class="pre">N</span> <span class="pre">=</span> <span class="pre">ker</span> <span class="pre">φ</span></code>. In that case the descended morphism is injective and we get a group isomorphism onto its image. This result is often called the first isomorphism theorem.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">{</span><span class="n">M</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">M</span><span class="o">]</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→*</span> <span class="n">M</span><span class="o">)</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">⧸</span> <span class="n">MonoidHom.ker</span> <span class="n">φ</span> <span class="bp">→*</span> <span class="n">MonoidHom.range</span> <span class="n">φ</span> <span class="o">:=</span> <span class="n">QuotientGroup.quotientKerEquivRange</span> <span class="n">φ</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">M</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">MonoidHom.ker</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">MonoidHom.range</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">QuotientGroup.quotientKerEquivRange</span><span class="w"> </span><span class="n">φ</span> </pre></div> </div> <p>Applying the universal property to a composition of a morphism <code class="docutils literal notranslate"><span class="pre">φ</span> <span class="pre">:</span> <span class="pre">G</span> <span class="pre">→*</span> <span class="pre">G'</span></code>
-
@@ -636,18 +637,18 @@ The condition required on <code class="docutils literal notranslate"><span class="pre">φ</span></code> is usually formulated by saying “<code class="docutils literal notranslate"><span class="pre">φ</span></code> should send <code class="docutils literal notranslate"><span class="pre">N</span></code> inside<code class="docutils literal notranslate"><span class="pre">N'</span></code>.” But this is equivalent to asking that <code class="docutils literal notranslate"><span class="pre">φ</span></code> should pull <code class="docutils literal notranslate"><span class="pre">N'</span></code> back over <code class="docutils literal notranslate"><span class="pre">N</span></code>, and the latter condition is nicer to work with since the definition of pullback does not involve an existential quantifier.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="n">G'</span><span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G'</span><span class="o">]</span> <span class="o">{</span><span class="n">N</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">}</span> <span class="o">[</span><span class="n">N.Normal</span><span class="o">]</span> <span class="o">{</span><span class="n">N'</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G'</span><span class="o">}</span> <span class="o">[</span><span class="n">N'.Normal</span><span class="o">]</span> <span class="o">{</span><span class="n">φ</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→*</span> <span class="n">G'</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">N</span> <span class="bp">≤</span> <span class="n">Subgroup.comap</span> <span class="n">φ</span> <span class="n">N'</span><span class="o">)</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">⧸</span> <span class="n">N</span> <span class="bp">→*</span> <span class="n">G'</span> <span class="bp">⧸</span> <span class="n">N'</span><span class="o">:=</span> <span class="n">QuotientGroup.map</span> <span class="n">N</span> <span class="n">N'</span> <span class="n">φ</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="n">G'</span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G'</span><span class="o">]</span> <span class="w"> </span><span class="o">{</span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">N.Normal</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">N'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G'</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">N'.Normal</span><span class="o">]</span> <span class="w"> </span><span class="o">{</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">G'</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">Subgroup.comap</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">N'</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">G'</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">N'</span><span class="o">:=</span> <span class="w"> </span><span class="n">QuotientGroup.map</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="n">N'</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>One subtle point to keep in mind is that the type <code class="docutils literal notranslate"><span class="pre">G</span> <span class="pre">⧸</span> <span class="pre">N</span></code> really depends on <code class="docutils literal notranslate"><span class="pre">N</span></code> (up to definitional equality), so having a proof that two normal subgroups <code class="docutils literal notranslate"><span class="pre">N</span></code> and <code class="docutils literal notranslate"><span class="pre">M</span></code> are equal is not enough to make the corresponding quotients equal. However the universal properties does give an isomorphism in this case.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">{</span><span class="n">M</span> <span class="n">N</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">}</span> <span class="o">[</span><span class="n">M.Normal</span><span class="o">]</span> <span class="o">[</span><span class="n">N.Normal</span><span class="o">]</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">M</span> <span class="bp">=</span> <span class="n">N</span><span class="o">)</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">⧸</span> <span class="n">M</span> <span class="bp">≃*</span> <span class="n">G</span> <span class="bp">⧸</span> <span class="n">N</span> <span class="o">:=</span> <span class="n">QuotientGroup.quotientMulEquivOfEq</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">M</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">M.Normal</span><span class="o">]</span> <span class="w"> </span><span class="o">[</span><span class="n">N.Normal</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">N</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="bp">≃*</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">QuotientGroup.quotientMulEquivOfEq</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>As a final series of exercises for this section, we will prove that if <code class="docutils literal notranslate"><span class="pre">H</span></code> and <code class="docutils literal notranslate"><span class="pre">K</span></code> are disjoint
-
@@ -657,46 +658,46 @@ then <code class="docutils literal notranslate"><span class="pre">G</span></code> is isomorphic to <code class="docutils literal notranslate"><span class="pre">H</span> <span class="pre">×</span> <span class="pre">K</span></code>. Recall that disjoint in this context means <code class="docutils literal notranslate"><span class="pre">H</span> <span class="pre">⊓</span> <span class="pre">K</span> <span class="pre">=</span> <span class="pre">⊥</span></code>.</p><p>We start with playing a bit with Lagrange’s lemma, without assuming the subgroups are normal or disjoint.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Group</span> <span class="n">G</span><span class="o">]</span> <span class="o">{</span><span class="n">H</span> <span class="n">K</span> <span class="o">:</span> <span class="n">Subgroup</span> <span class="n">G</span><span class="o">}</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Group</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">H</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subgroup</span><span class="w"> </span><span class="n">G</span><span class="o">}</span> <span class="kn">open</span> <span class="n">MonoidHom</span> <span class="kn">open</span><span class="w"> </span><span class="n">MonoidHom</span> <span class="k">#check</span> <span class="n">Nat.card_pos</span> <span class="c1">-- The nonempty argument will be automatically inferred for subgroups</span> <span class="k">#check</span> <span class="n">Subgroup.index_eq_card</span> <span class="k">#check</span> <span class="n">Subgroup.index_mul_card</span> <span class="k">#check</span> <span class="n">Nat.eq_of_mul_eq_mul_right</span> <span class="k">#check</span><span class="w"> </span><span class="n">Nat.card_pos</span><span class="w"> </span><span class="c1">-- The nonempty argument will be automatically inferred for subgroups</span> <span class="k">#check</span><span class="w"> </span><span class="n">Subgroup.index_eq_card</span> <span class="k">#check</span><span class="w"> </span><span class="n">Subgroup.index_mul_card</span> <span class="k">#check</span><span class="w"> </span><span class="n">Nat.eq_of_mul_eq_mul_right</span> <span class="kd">lemma</span> <span class="n">aux_card_eq</span> <span class="o">[</span><span class="n">Finite</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">h'</span> <span class="o">:</span> <span class="n">Nat.card</span> <span class="n">G</span> <span class="bp">=</span> <span class="n">Nat.card</span> <span class="n">H</span> <span class="bp">*</span> <span class="n">Nat.card</span> <span class="n">K</span><span class="o">)</span> <span class="o">:</span> <span class="n">Nat.card</span> <span class="o">(</span><span class="n">G</span> <span class="bp">⧸</span> <span class="n">H</span><span class="o">)</span> <span class="bp">=</span> <span class="n">Nat.card</span> <span class="n">K</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">lemma</span><span class="w"> </span><span class="n">aux_card_eq</span><span class="w"> </span><span class="o">[</span><span class="n">Finite</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat.card</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">Nat.card</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">Nat.card</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Nat.card</span><span class="w"> </span><span class="o">(</span><span class="n">G</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">Nat.card</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>From now on, we assume that our subgroups are normal and disjoint, and we assume the cardinality condition. Now we construct the first building block of the desired isomorphism.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">[</span><span class="n">H.Normal</span><span class="o">]</span> <span class="o">[</span><span class="n">K.Normal</span><span class="o">]</span> <span class="o">[</span><span class="n">Fintype</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">Disjoint</span> <span class="n">H</span> <span class="n">K</span><span class="o">)</span> <span class="o">(</span><span class="n">h'</span> <span class="o">:</span> <span class="n">Nat.card</span> <span class="n">G</span> <span class="bp">=</span> <span class="n">Nat.card</span> <span class="n">H</span> <span class="bp">*</span> <span class="n">Nat.card</span> <span class="n">K</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">[</span><span class="n">H.Normal</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">K.Normal</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Fintype</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Disjoint</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="n">K</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat.card</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">Nat.card</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">Nat.card</span><span class="w"> </span><span class="n">K</span><span class="o">)</span> <span class="k">#check</span> <span class="n">Nat.bijective_iff_injective_and_card</span> <span class="k">#check</span> <span class="n">ker_eq_bot_iff</span> <span class="k">#check</span> <span class="n">restrict</span> <span class="k">#check</span> <span class="n">ker_restrict</span> <span class="k">#check</span><span class="w"> </span><span class="n">Nat.bijective_iff_injective_and_card</span> <span class="k">#check</span><span class="w"> </span><span class="n">ker_eq_bot_iff</span> <span class="k">#check</span><span class="w"> </span><span class="n">restrict</span> <span class="k">#check</span><span class="w"> </span><span class="n">ker_restrict</span> <span class="kd">def</span> <span class="n">iso₁</span> <span class="o">[</span><span class="n">Fintype</span> <span class="n">G</span><span class="o">]</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">Disjoint</span> <span class="n">H</span> <span class="n">K</span><span class="o">)</span> <span class="o">(</span><span class="n">h'</span> <span class="o">:</span> <span class="n">Nat.card</span> <span class="n">G</span> <span class="bp">=</span> <span class="n">Nat.card</span> <span class="n">H</span> <span class="bp">*</span> <span class="n">Nat.card</span> <span class="n">K</span><span class="o">)</span> <span class="o">:</span> <span class="n">K</span> <span class="bp">≃*</span> <span class="n">G</span> <span class="bp">⧸</span> <span class="n">H</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">def</span><span class="w"> </span><span class="n">iso₁</span><span class="w"> </span><span class="o">[</span><span class="n">Fintype</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Disjoint</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nat.card</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">Nat.card</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">Nat.card</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="bp">≃*</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Now we can define our second building block. We will need <code class="docutils literal notranslate"><span class="pre">MonoidHom.prod</span></code>, which builds a morphism from <code class="docutils literal notranslate"><span class="pre">G₀</span></code> to <code class="docutils literal notranslate"><span class="pre">G₁</span> <span class="pre">×</span> <span class="pre">G₂</span></code> out of morphisms from <code class="docutils literal notranslate"><span class="pre">G₀</span></code> to <code class="docutils literal notranslate"><span class="pre">G₁</span></code> and <code class="docutils literal notranslate"><span class="pre">G₂</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">iso₂</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">≃*</span> <span class="o">(</span><span class="n">G</span> <span class="bp">⧸</span> <span class="n">K</span><span class="o">)</span> <span class="bp">×</span> <span class="o">(</span><span class="n">G</span> <span class="bp">⧸</span> <span class="n">H</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">iso₂</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">≃*</span><span class="w"> </span><span class="o">(</span><span class="n">G</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="o">(</span><span class="n">G</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>We are ready to put all pieces together.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="n">MulEquiv.prodCongr</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="n">MulEquiv.prodCongr</span> <span class="kd">def</span> <span class="n">finalIso</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">≃*</span> <span class="n">H</span> <span class="bp">×</span> <span class="n">K</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">def</span><span class="w"> </span><span class="n">finalIso</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">≃*</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> </section>
-
@@ -708,7 +709,7 @@ <span id="index-4"></span><h3><span class="section-number">8.2.1. </span>Rings, their units, morphisms and subrings<a class="headerlink" href="#rings-their-units-morphisms-and-subrings" title="Link to this heading"></a></h3><p>The type of ring structures on a type <code class="docutils literal notranslate"><span class="pre">R</span></code> is <code class="docutils literal notranslate"><span class="pre">Ring</span> <span class="pre">R</span></code>. The variant where multiplication is assumed to be commutative is <code class="docutils literal notranslate"><span class="pre">CommRing</span> <span class="pre">R</span></code>. We have already seen that the <code class="docutils literal notranslate"><span class="pre">ring</span></code> tactic will prove any equality that follows from the axioms of a commutative ring.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">x</span> <span class="bp">+</span> <span class="n">y</span><span class="o">)</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">=</span> <span class="n">x</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="n">y</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="mi">2</span> <span class="bp">*</span> <span class="n">x</span> <span class="bp">*</span> <span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ring</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">ring</span> </pre></div> </div> <p>More exotic variants do not require that the addition on <code class="docutils literal notranslate"><span class="pre">R</span></code> forms a group but only an additive
-
@@ -718,7 +719,7 @@ of functions taking values in the natural numbers.Another important example is the type of ideals in a ring, which will be discussed below. The name of the <code class="docutils literal notranslate"><span class="pre">ring</span></code> tactic is doubly misleading, since it assumes commutativity but works in semirings as well. In other words, it applies to any <code class="docutils literal notranslate"><span class="pre">CommSemiring</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">x</span> <span class="bp">+</span> <span class="n">y</span><span class="o">)</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">=</span> <span class="n">x</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="n">y</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="mi">2</span> <span class="bp">*</span> <span class="n">x</span> <span class="bp">*</span> <span class="n">y</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ring</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">ring</span> </pre></div> </div> <p>There are also versions of the ring and semiring classes that do not assume the existence of a
-
@@ -735,27 +736,27 @@ This implementation detail is relevant mainly when defining computable functions. In mostsituations one can use <code class="docutils literal notranslate"><span class="pre">IsUnit.unit</span> <span class="pre">{x</span> <span class="pre">:</span> <span class="pre">M}</span> <span class="pre">:</span> <span class="pre">IsUnit</span> <span class="pre">x</span> <span class="pre">→</span> <span class="pre">Mˣ</span></code> to build a unit. In the commutative case, one also has <code class="docutils literal notranslate"><span class="pre">Units.mkOfMulEqOne</span> <span class="pre">(x</span> <span class="pre">y</span> <span class="pre">:</span> <span class="pre">M)</span> <span class="pre">:</span> <span class="pre">x</span> <span class="pre">*</span> <span class="pre">y</span> <span class="pre">=</span> <span class="pre">1</span> <span class="pre">→</span> <span class="pre">Mˣ</span></code> which builds <code class="docutils literal notranslate"><span class="pre">x</span></code> seen as unit.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">ℤ</span><span class="bp">ˣ</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">=</span> <span class="mi">1</span> <span class="bp">∨</span> <span class="n">x</span> <span class="bp">=</span> <span class="bp">-</span><span class="mi">1</span> <span class="o">:=</span> <span class="n">Int.units_eq_one_or</span> <span class="n">x</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℤ</span><span class="bp">ˣ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">∨</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">-</span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Int.units_eq_one_or</span><span class="w"> </span><span class="n">x</span> <span class="kd">example</span> <span class="o">{</span><span class="n">M</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">M</span><span class="bp">ˣ</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">M</span><span class="o">)</span> <span class="bp">*</span> <span class="n">x</span><span class="bp">⁻¹</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="n">Units.mul_inv</span> <span class="n">x</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">M</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="bp">ˣ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">x</span><span class="bp">⁻¹</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Units.mul_inv</span><span class="w"> </span><span class="n">x</span> <span class="kd">example</span> <span class="o">{</span><span class="n">M</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Monoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">:</span> <span class="n">Group</span> <span class="n">M</span><span class="bp">ˣ</span> <span class="o">:=</span> <span class="n">inferInstance</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">M</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Monoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Group</span><span class="w"> </span><span class="n">M</span><span class="bp">ˣ</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">inferInstance</span> </pre></div> </div> <p>The type of ring morphisms between two (semi)-rings <code class="docutils literal notranslate"><span class="pre">R</span></code> and <code class="docutils literal notranslate"><span class="pre">S</span></code> is <code class="docutils literal notranslate"><span class="pre">RingHom</span> <span class="pre">R</span> <span class="pre">S</span></code>, with notation <code class="docutils literal notranslate"><span class="pre">R</span> <span class="pre">→+*</span> <span class="pre">S</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="n">S</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Ring</span> <span class="n">R</span><span class="o">]</span> <span class="o">[</span><span class="n">Ring</span> <span class="n">S</span><span class="o">]</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">R</span> <span class="bp">→+*</span> <span class="n">S</span><span class="o">)</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="n">f</span> <span class="o">(</span><span class="n">x</span> <span class="bp">+</span> <span class="n">y</span><span class="o">)</span> <span class="bp">=</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">f</span> <span class="n">y</span> <span class="o">:=</span> <span class="n">f.map_add</span> <span class="n">x</span> <span class="n">y</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Ring</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Ring</span><span class="w"> </span><span class="n">S</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="bp">→+*</span><span class="w"> </span><span class="n">S</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">f.map_add</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span> <span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="n">S</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Ring</span> <span class="n">R</span><span class="o">]</span> <span class="o">[</span><span class="n">Ring</span> <span class="n">S</span><span class="o">]</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">R</span> <span class="bp">→+*</span> <span class="n">S</span><span class="o">)</span> <span class="o">:</span> <span class="n">R</span><span class="bp">ˣ</span> <span class="bp">→*</span> <span class="n">S</span><span class="bp">ˣ</span> <span class="o">:=</span> <span class="n">Units.map</span> <span class="n">f</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Ring</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Ring</span><span class="w"> </span><span class="n">S</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="bp">→+*</span><span class="w"> </span><span class="n">S</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="bp">ˣ</span><span class="w"> </span><span class="bp">→*</span><span class="w"> </span><span class="n">S</span><span class="bp">ˣ</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Units.map</span><span class="w"> </span><span class="n">f</span> </pre></div> </div> <p>The isomorphism variant is <code class="docutils literal notranslate"><span class="pre">RingEquiv</span></code>, with notation <code class="docutils literal notranslate"><span class="pre">≃+*</span></code>.</p> <p>As with submonoids and subgroups, there is a <code class="docutils literal notranslate"><span class="pre">Subring</span> <span class="pre">R</span></code> type for subrings of a ring <code class="docutils literal notranslate"><span class="pre">R</span></code>, but this type is a lot less useful than the type of subgroups since one cannot quotient a ring by a subring.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Ring</span> <span class="n">R</span><span class="o">]</span> <span class="o">(</span><span class="n">S</span> <span class="o">:</span> <span class="n">Subring</span> <span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="n">Ring</span> <span class="n">S</span> <span class="o">:=</span> <span class="n">inferInstance</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Ring</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">S</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Subring</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Ring</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">inferInstance</span> </pre></div> </div> <p>Also notice that <code class="docutils literal notranslate"><span class="pre">RingHom.range</span></code> produces a subring.</p>
-
@@ -772,40 +773,40 @@ ideals. But anonymous projection notation won’t always work as expected. For instance,one cannot replace <code class="docutils literal notranslate"><span class="pre">Ideal.Quotient.mk</span> <span class="pre">I</span></code> by <code class="docutils literal notranslate"><span class="pre">I.Quotient.mk</span></code> in the snippet below because there are two <code class="docutils literal notranslate"><span class="pre">.</span></code>s and so it will parse as <code class="docutils literal notranslate"><span class="pre">(Ideal.Quotient</span> <span class="pre">I).mk</span></code>; but <code class="docutils literal notranslate"><span class="pre">Ideal.Quotient</span></code> by itself doesn’t exist.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="o">(</span><span class="n">I</span> <span class="o">:</span> <span class="n">Ideal</span> <span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="n">R</span> <span class="bp">→+*</span> <span class="n">R</span> <span class="bp">⧸</span> <span class="n">I</span> <span class="o">:=</span> <span class="n">Ideal.Quotient.mk</span> <span class="n">I</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">I</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Ideal</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="bp">→+*</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Ideal.Quotient.mk</span><span class="w"> </span><span class="n">I</span> <span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="o">{</span><span class="n">a</span> <span class="o">:</span> <span class="n">R</span><span class="o">}</span> <span class="o">{</span><span class="n">I</span> <span class="o">:</span> <span class="n">Ideal</span> <span class="n">R</span><span class="o">}</span> <span class="o">:</span> <span class="n">Ideal.Quotient.mk</span> <span class="n">I</span> <span class="n">a</span> <span class="bp">=</span> <span class="mi">0</span> <span class="bp">↔</span> <span class="n">a</span> <span class="bp">∈</span> <span class="n">I</span> <span class="o">:=</span> <span class="n">Ideal.Quotient.eq_zero_iff_mem</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">I</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Ideal</span><span class="w"> </span><span class="n">R</span><span class="o">}</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Ideal.Quotient.mk</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Ideal.Quotient.eq_zero_iff_mem</span> </pre></div> </div> <p>The universal property of quotient rings is <code class="docutils literal notranslate"><span class="pre">Ideal.Quotient.lift</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="n">S</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">S</span><span class="o">]</span> <span class="o">(</span><span class="n">I</span> <span class="o">:</span> <span class="n">Ideal</span> <span class="n">R</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">R</span> <span class="bp">→+*</span> <span class="n">S</span><span class="o">)</span> <span class="o">(</span><span class="n">H</span> <span class="o">:</span> <span class="n">I</span> <span class="bp">≤</span> <span class="n">RingHom.ker</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="n">R</span> <span class="bp">⧸</span> <span class="n">I</span> <span class="bp">→+*</span> <span class="n">S</span> <span class="o">:=</span> <span class="n">Ideal.Quotient.lift</span> <span class="n">I</span> <span class="n">f</span> <span class="n">H</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">S</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">I</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Ideal</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="bp">→+*</span><span class="w"> </span><span class="n">S</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">RingHom.ker</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="bp">→+*</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Ideal.Quotient.lift</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">H</span> </pre></div> </div> <p>In particular it leads to the first isomorphism theorem for rings.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="n">S</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">S</span><span class="o">](</span><span class="n">f</span> <span class="o">:</span> <span class="n">R</span> <span class="bp">→+*</span> <span class="n">S</span><span class="o">)</span> <span class="o">:</span> <span class="n">R</span> <span class="bp">⧸</span> <span class="n">RingHom.ker</span> <span class="n">f</span> <span class="bp">≃+*</span> <span class="n">f.range</span> <span class="o">:=</span> <span class="n">RingHom.quotientKerEquivRange</span> <span class="n">f</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">S</span><span class="o">](</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="bp">→+*</span><span class="w"> </span><span class="n">S</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">RingHom.ker</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">≃+*</span><span class="w"> </span><span class="n">f.range</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">RingHom.quotientKerEquivRange</span><span class="w"> </span><span class="n">f</span> </pre></div> </div> <p>Ideals form a complete lattice structure with the inclusion relation, as well as a semiring structure. These two structures interact nicely.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="o">{</span><span class="n">I</span> <span class="n">J</span> <span class="o">:</span> <span class="n">Ideal</span> <span class="n">R</span><span class="o">}</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">I</span><span class="w"> </span><span class="n">J</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Ideal</span><span class="w"> </span><span class="n">R</span><span class="o">}</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">I</span> <span class="bp">+</span> <span class="n">J</span> <span class="bp">=</span> <span class="n">I</span> <span class="bp">⊔</span> <span class="n">J</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">J</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">J</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">rfl</span> <span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">R</span><span class="o">}</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">I</span> <span class="bp">+</span> <span class="n">J</span> <span class="bp">↔</span> <span class="bp">∃</span> <span class="n">a</span> <span class="bp">∈</span> <span class="n">I</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">b</span> <span class="bp">∈</span> <span class="n">J</span><span class="o">,</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">x</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="o">[</span><span class="n">Submodule.mem_sup</span><span class="o">]</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">J</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">I</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">J</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">Submodule.mem_sup</span><span class="o">]</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">I</span> <span class="bp">*</span> <span class="n">J</span> <span class="bp">≤</span> <span class="n">J</span> <span class="o">:=</span> <span class="n">Ideal.mul_le_left</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">J</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">J</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Ideal.mul_le_left</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">I</span> <span class="bp">*</span> <span class="n">J</span> <span class="bp">≤</span> <span class="n">I</span> <span class="o">:=</span> <span class="n">Ideal.mul_le_right</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">J</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Ideal.mul_le_right</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">I</span> <span class="bp">*</span> <span class="n">J</span> <span class="bp">≤</span> <span class="n">I</span> <span class="bp">⊓</span> <span class="n">J</span> <span class="o">:=</span> <span class="n">Ideal.mul_le_inf</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">J</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">J</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Ideal.mul_le_inf</span> </pre></div> </div> <p>One can use ring morphisms to push ideals forward and pull them back using <code class="docutils literal notranslate"><span class="pre">Ideal.map</span></code> and
-
@@ -813,123 +814,123 @@ <code class="docutils literal notranslate"><span class="pre">Ideal.comap</span></code>, respectively. As usual,the latter is more convenient to use since it does not involve an existential quantifier. This explains why it is used to state the condition that allows us to build morphisms between quotient rings.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="n">S</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">S</span><span class="o">]</span> <span class="o">(</span><span class="n">I</span> <span class="o">:</span> <span class="n">Ideal</span> <span class="n">R</span><span class="o">)</span> <span class="o">(</span><span class="n">J</span> <span class="o">:</span> <span class="n">Ideal</span> <span class="n">S</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">R</span> <span class="bp">→+*</span> <span class="n">S</span><span class="o">)</span> <span class="o">(</span><span class="n">H</span> <span class="o">:</span> <span class="n">I</span> <span class="bp">≤</span> <span class="n">Ideal.comap</span> <span class="n">f</span> <span class="n">J</span><span class="o">)</span> <span class="o">:</span> <span class="n">R</span> <span class="bp">⧸</span> <span class="n">I</span> <span class="bp">→+*</span> <span class="n">S</span> <span class="bp">⧸</span> <span class="n">J</span> <span class="o">:=</span> <span class="n">Ideal.quotientMap</span> <span class="n">J</span> <span class="n">f</span> <span class="n">H</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">S</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">I</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Ideal</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">J</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Ideal</span><span class="w"> </span><span class="n">S</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="bp">→+*</span><span class="w"> </span><span class="n">S</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">Ideal.comap</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">J</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="bp">→+*</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">J</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Ideal.quotientMap</span><span class="w"> </span><span class="n">J</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">H</span> </pre></div> </div> <p>One subtle point is that the type <code class="docutils literal notranslate"><span class="pre">R</span> <span class="pre">⧸</span> <span class="pre">I</span></code> really depends on <code class="docutils literal notranslate"><span class="pre">I</span></code> (up to definitional equality), so having a proof that two ideals <code class="docutils literal notranslate"><span class="pre">I</span></code> and <code class="docutils literal notranslate"><span class="pre">J</span></code> are equal is not enough to make the corresponding quotients equal. However, the universal properties do provide an isomorphism in this case.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="o">{</span><span class="n">I</span> <span class="n">J</span> <span class="o">:</span> <span class="n">Ideal</span> <span class="n">R</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">I</span> <span class="bp">=</span> <span class="n">J</span><span class="o">)</span> <span class="o">:</span> <span class="n">R</span> <span class="bp">⧸</span> <span class="n">I</span> <span class="bp">≃+*</span> <span class="n">R</span> <span class="bp">⧸</span> <span class="n">J</span> <span class="o">:=</span> <span class="n">Ideal.quotEquivOfEq</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">I</span><span class="w"> </span><span class="n">J</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Ideal</span><span class="w"> </span><span class="n">R</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">J</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="bp">≃+*</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">J</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Ideal.quotEquivOfEq</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>We can now present the Chinese remainder isomorphism as an example. Pay attention to the difference between the indexed infimum symbol <code class="docutils literal notranslate"><span class="pre">⨅</span></code> and the big product of types symbol <code class="docutils literal notranslate"><span class="pre">Π</span></code>. Depending on your font, those can be pretty hard to distinguish.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="o">{</span><span class="n">ι</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Fintype</span> <span class="n">ι</span><span class="o">]</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">Ideal</span> <span class="n">R</span><span class="o">)</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">i</span> <span class="n">j</span><span class="o">,</span> <span class="n">i</span> <span class="bp">≠</span> <span class="n">j</span> <span class="bp">→</span> <span class="n">IsCoprime</span> <span class="o">(</span><span class="n">f</span> <span class="n">i</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="n">j</span><span class="o">))</span> <span class="o">:</span> <span class="o">(</span><span class="n">R</span> <span class="bp">⧸</span> <span class="bp">⨅</span> <span class="n">i</span><span class="o">,</span> <span class="n">f</span> <span class="n">i</span><span class="o">)</span> <span class="bp">≃+*</span> <span class="bp">Π</span> <span class="n">i</span><span class="o">,</span> <span class="n">R</span> <span class="bp">⧸</span> <span class="n">f</span> <span class="n">i</span> <span class="o">:=</span> <span class="n">Ideal.quotientInfRingEquivPiQuotient</span> <span class="n">f</span> <span class="n">hf</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">ι</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Fintype</span><span class="w"> </span><span class="n">ι</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Ideal</span><span class="w"> </span><span class="n">R</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="n">j</span><span class="o">,</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">IsCoprime</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">j</span><span class="o">))</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">R</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="bp">⨅</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">≃+*</span><span class="w"> </span><span class="bp">Π</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Ideal.quotientInfRingEquivPiQuotient</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">hf</span> </pre></div> </div> <p>The elementary version of the Chinese remainder theorem, a statement about <code class="docutils literal notranslate"><span class="pre">ZMod</span></code>, can be easily deduced from the previous one:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">BigOperators</span> <span class="n">PiNotation</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">BigOperators</span><span class="w"> </span><span class="n">PiNotation</span> <span class="kd">example</span> <span class="o">{</span><span class="n">ι</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Fintype</span> <span class="n">ι</span><span class="o">]</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">coprime</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">i</span> <span class="n">j</span><span class="o">,</span> <span class="n">i</span> <span class="bp">≠</span> <span class="n">j</span> <span class="bp">→</span> <span class="o">(</span><span class="n">a</span> <span class="n">i</span><span class="o">)</span><span class="bp">.</span><span class="n">Coprime</span> <span class="o">(</span><span class="n">a</span> <span class="n">j</span><span class="o">))</span> <span class="o">:</span> <span class="n">ZMod</span> <span class="o">(</span><span class="bp">∏</span> <span class="n">i</span><span class="o">,</span> <span class="n">a</span> <span class="n">i</span><span class="o">)</span> <span class="bp">≃+*</span> <span class="bp">Π</span> <span class="n">i</span><span class="o">,</span> <span class="n">ZMod</span> <span class="o">(</span><span class="n">a</span> <span class="n">i</span><span class="o">)</span> <span class="o">:=</span> <span class="n">ZMod.prodEquivPi</span> <span class="n">a</span> <span class="n">coprime</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">ι</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Fintype</span><span class="w"> </span><span class="n">ι</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">coprime</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="n">j</span><span class="o">,</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="bp">.</span><span class="n">Coprime</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">j</span><span class="o">))</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">ZMod</span><span class="w"> </span><span class="o">(</span><span class="bp">∏</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">≃+*</span><span class="w"> </span><span class="bp">Π</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">ZMod</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">ZMod.prodEquivPi</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">coprime</span> </pre></div> </div> <p>As a series of exercises, we will reprove the Chinese remainder theorem in the general case.</p> <p>We first need to define the map appearing in the theorem, as a ring morphism, using the universal property of quotient rings.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">ι</span> <span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="kn">open</span> <span class="n">Ideal</span> <span class="n">Quotient</span> <span class="n">Function</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">ι</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span> <span class="kn">open</span><span class="w"> </span><span class="n">Ideal</span><span class="w"> </span><span class="n">Quotient</span><span class="w"> </span><span class="n">Function</span> <span class="k">#check</span> <span class="k">Pi</span><span class="bp">.</span><span class="n">ringHom</span> <span class="k">#check</span> <span class="n">ker_Pi_Quotient_mk</span> <span class="k">#check</span><span class="w"> </span><span class="k">Pi</span><span class="bp">.</span><span class="n">ringHom</span> <span class="k">#check</span><span class="w"> </span><span class="n">ker_Pi_Quotient_mk</span> <span class="sd">/-- The homomorphism from ``R ⧸ ⨅ i, I i`` to ``Π i, R ⧸ I i`` featured in the Chinese</span> <span class="sd"> Remainder Theorem. -/</span> <span class="kd">def</span> <span class="n">chineseMap</span> <span class="o">(</span><span class="n">I</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">Ideal</span> <span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">R</span> <span class="bp">⧸</span> <span class="bp">⨅</span> <span class="n">i</span><span class="o">,</span> <span class="n">I</span> <span class="n">i</span><span class="o">)</span> <span class="bp">→+*</span> <span class="bp">Π</span> <span class="n">i</span><span class="o">,</span> <span class="n">R</span> <span class="bp">⧸</span> <span class="n">I</span> <span class="n">i</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">def</span><span class="w"> </span><span class="n">chineseMap</span><span class="w"> </span><span class="o">(</span><span class="n">I</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Ideal</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">R</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="bp">⨅</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">→+*</span><span class="w"> </span><span class="bp">Π</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Make sure the following next two lemmas can be proven by <code class="docutils literal notranslate"><span class="pre">rfl</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">lemma</span> <span class="n">chineseMap_mk</span> <span class="o">(</span><span class="n">I</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">Ideal</span> <span class="n">R</span><span class="o">)</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="n">chineseMap</span> <span class="n">I</span> <span class="o">(</span><span class="n">Quotient.mk</span> <span class="n">_</span> <span class="n">x</span><span class="o">)</span> <span class="bp">=</span> <span class="k">fun</span> <span class="n">i</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">↦</span> <span class="n">Ideal.Quotient.mk</span> <span class="o">(</span><span class="n">I</span> <span class="n">i</span><span class="o">)</span> <span class="n">x</span> <span class="o">:=</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">lemma</span><span class="w"> </span><span class="n">chineseMap_mk</span><span class="w"> </span><span class="o">(</span><span class="n">I</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Ideal</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">chineseMap</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="o">(</span><span class="n">Quotient.mk</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">Ideal.Quotient.mk</span><span class="w"> </span><span class="o">(</span><span class="n">I</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">lemma</span> <span class="n">chineseMap_mk'</span> <span class="o">(</span><span class="n">I</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">Ideal</span> <span class="n">R</span><span class="o">)</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">(</span><span class="n">i</span> <span class="o">:</span> <span class="n">ι</span><span class="o">)</span> <span class="o">:</span> <span class="n">chineseMap</span> <span class="n">I</span> <span class="o">(</span><span class="n">mk</span> <span class="n">_</span> <span class="n">x</span><span class="o">)</span> <span class="n">i</span> <span class="bp">=</span> <span class="n">mk</span> <span class="o">(</span><span class="n">I</span> <span class="n">i</span><span class="o">)</span> <span class="n">x</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">lemma</span><span class="w"> </span><span class="n">chineseMap_mk'</span><span class="w"> </span><span class="o">(</span><span class="n">I</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Ideal</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">i</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">chineseMap</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="o">(</span><span class="n">mk</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">mk</span><span class="w"> </span><span class="o">(</span><span class="n">I</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>The next lemma proves the easy half of the Chinese remainder theorem, without any assumption on the family of ideals. The proof is less than one line long.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="n">injective_lift_iff</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="n">injective_lift_iff</span> <span class="kd">lemma</span> <span class="n">chineseMap_inj</span> <span class="o">(</span><span class="n">I</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">Ideal</span> <span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="n">Injective</span> <span class="o">(</span><span class="n">chineseMap</span> <span class="n">I</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">lemma</span><span class="w"> </span><span class="n">chineseMap_inj</span><span class="w"> </span><span class="o">(</span><span class="n">I</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Ideal</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="o">(</span><span class="n">chineseMap</span><span class="w"> </span><span class="n">I</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>We are now ready for the heart of the theorem, which will show the surjectivity of our <code class="docutils literal notranslate"><span class="pre">chineseMap</span></code>. First we need to know the different ways one can express the coprimality (also called co-maximality assumption). Only the first two will be needed below.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="n">IsCoprime</span> <span class="k">#check</span> <span class="n">isCoprime_iff_add</span> <span class="k">#check</span> <span class="n">isCoprime_iff_exists</span> <span class="k">#check</span> <span class="n">isCoprime_iff_sup_eq</span> <span class="k">#check</span> <span class="n">isCoprime_iff_codisjoint</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="n">IsCoprime</span> <span class="k">#check</span><span class="w"> </span><span class="n">isCoprime_iff_add</span> <span class="k">#check</span><span class="w"> </span><span class="n">isCoprime_iff_exists</span> <span class="k">#check</span><span class="w"> </span><span class="n">isCoprime_iff_sup_eq</span> <span class="k">#check</span><span class="w"> </span><span class="n">isCoprime_iff_codisjoint</span> </pre></div> </div> <p>We take the opportunity to use induction on <code class="docutils literal notranslate"><span class="pre">Finset</span></code>. Relevant lemmas on <code class="docutils literal notranslate"><span class="pre">Finset</span></code> are given below. Remember that the <code class="docutils literal notranslate"><span class="pre">ring</span></code> tactic works for semirings and that the ideals of a ring form a semiring.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="n">Finset.mem_insert_of_mem</span> <span class="k">#check</span> <span class="n">Finset.mem_insert_self</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="n">Finset.mem_insert_of_mem</span> <span class="k">#check</span><span class="w"> </span><span class="n">Finset.mem_insert_self</span> <span class="kd">theorem</span> <span class="n">isCoprime_Inf</span> <span class="o">{</span><span class="n">I</span> <span class="o">:</span> <span class="n">Ideal</span> <span class="n">R</span><span class="o">}</span> <span class="o">{</span><span class="n">J</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">Ideal</span> <span class="n">R</span><span class="o">}</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">Finset</span> <span class="n">ι</span><span class="o">}</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">j</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="n">IsCoprime</span> <span class="n">I</span> <span class="o">(</span><span class="n">J</span> <span class="n">j</span><span class="o">))</span> <span class="o">:</span> <span class="n">IsCoprime</span> <span class="n">I</span> <span class="o">(</span><span class="bp">⨅</span> <span class="n">j</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="n">J</span> <span class="n">j</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">classical</span> <span class="n">simp_rw</span> <span class="o">[</span><span class="n">isCoprime_iff_add</span><span class="o">]</span> <span class="n">at</span> <span class="bp">*</span> <span class="n">induction</span> <span class="n">s</span> <span class="n">using</span> <span class="n">Finset.induction</span> <span class="k">with</span> <span class="bp">|</span> <span class="n">empty</span> <span class="bp">=></span> <span class="n">simp</span> <span class="bp">|</span> <span class="bp">@</span><span class="n">insert</span> <span class="n">i</span> <span class="n">s</span> <span class="n">_</span> <span class="n">hs</span> <span class="bp">=></span> <span class="n">rw</span> <span class="o">[</span><span class="n">Finset.iInf_insert</span><span class="o">,</span> <span class="n">inf_comm</span><span class="o">,</span> <span class="n">one_eq_top</span><span class="o">,</span> <span class="n">eq_top_iff</span><span class="o">,</span> <span class="bp">←</span> <span class="n">one_eq_top</span><span class="o">]</span> <span class="n">set</span> <span class="n">K</span> <span class="o">:=</span> <span class="bp">⨅</span> <span class="n">j</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="n">J</span> <span class="n">j</span> <span class="k">calc</span> <span class="mi">1</span> <span class="bp">=</span> <span class="n">I</span> <span class="bp">+</span> <span class="n">K</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">_</span> <span class="bp">=</span> <span class="n">I</span> <span class="bp">+</span> <span class="n">K</span> <span class="bp">*</span> <span class="o">(</span><span class="n">I</span> <span class="bp">+</span> <span class="n">J</span> <span class="n">i</span><span class="o">)</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">_</span> <span class="bp">=</span> <span class="o">(</span><span class="mi">1</span> <span class="bp">+</span> <span class="n">K</span><span class="o">)</span> <span class="bp">*</span> <span class="n">I</span> <span class="bp">+</span> <span class="n">K</span> <span class="bp">*</span> <span class="n">J</span> <span class="n">i</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">_</span> <span class="bp">≤</span> <span class="n">I</span> <span class="bp">+</span> <span class="n">K</span> <span class="bp">⊓</span> <span class="n">J</span> <span class="n">i</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">theorem</span><span class="w"> </span><span class="n">isCoprime_Inf</span><span class="w"> </span><span class="o">{</span><span class="n">I</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Ideal</span><span class="w"> </span><span class="n">R</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">J</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Ideal</span><span class="w"> </span><span class="n">R</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Finset</span><span class="w"> </span><span class="n">ι</span><span class="o">}</span> <span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">IsCoprime</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="o">(</span><span class="n">J</span><span class="w"> </span><span class="n">j</span><span class="o">))</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsCoprime</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="o">(</span><span class="bp">⨅</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">J</span><span class="w"> </span><span class="n">j</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">classical</span> <span class="w"> </span><span class="n">simp_rw</span><span class="w"> </span><span class="o">[</span><span class="n">isCoprime_iff_add</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="bp">*</span> <span class="w"> </span><span class="n">induction</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">using</span><span class="w"> </span><span class="n">Finset.induction</span><span class="w"> </span><span class="k">with</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">empty</span><span class="w"> </span><span class="bp">=></span> <span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="bp">@</span><span class="n">insert</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">hs</span><span class="w"> </span><span class="bp">=></span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">Finset.iInf_insert</span><span class="o">,</span><span class="w"> </span><span class="n">inf_comm</span><span class="o">,</span><span class="w"> </span><span class="n">one_eq_top</span><span class="o">,</span><span class="w"> </span><span class="n">eq_top_iff</span><span class="o">,</span><span class="w"> </span><span class="bp">←</span><span class="w"> </span><span class="n">one_eq_top</span><span class="o">]</span> <span class="w"> </span><span class="n">set</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="bp">⨅</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">J</span><span class="w"> </span><span class="n">j</span> <span class="w"> </span><span class="k">calc</span> <span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">I</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">J</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="mi">1</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">J</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">J</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>We can now prove surjectivity of the map appearing in the Chinese remainder theorem.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">lemma</span> <span class="n">chineseMap_surj</span> <span class="o">[</span><span class="n">Fintype</span> <span class="n">ι</span><span class="o">]</span> <span class="o">{</span><span class="n">I</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">Ideal</span> <span class="n">R</span><span class="o">}</span> <span class="o">(</span><span class="n">hI</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">i</span> <span class="n">j</span><span class="o">,</span> <span class="n">i</span> <span class="bp">≠</span> <span class="n">j</span> <span class="bp">→</span> <span class="n">IsCoprime</span> <span class="o">(</span><span class="n">I</span> <span class="n">i</span><span class="o">)</span> <span class="o">(</span><span class="n">I</span> <span class="n">j</span><span class="o">))</span> <span class="o">:</span> <span class="n">Surjective</span> <span class="o">(</span><span class="n">chineseMap</span> <span class="n">I</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">classical</span> <span class="n">intro</span> <span class="n">g</span> <span class="n">choose</span> <span class="n">f</span> <span class="n">hf</span> <span class="n">using</span> <span class="k">fun</span> <span class="n">i</span> <span class="bp">↦</span> <span class="n">Ideal.Quotient.mk_surjective</span> <span class="o">(</span><span class="n">g</span> <span class="n">i</span><span class="o">)</span> <span class="k">have</span> <span class="n">key</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">i</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">e</span> <span class="o">:</span> <span class="n">R</span><span class="o">,</span> <span class="n">mk</span> <span class="o">(</span><span class="n">I</span> <span class="n">i</span><span class="o">)</span> <span class="n">e</span> <span class="bp">=</span> <span class="mi">1</span> <span class="bp">∧</span> <span class="bp">∀</span> <span class="n">j</span><span class="o">,</span> <span class="n">j</span> <span class="bp">≠</span> <span class="n">i</span> <span class="bp">→</span> <span class="n">mk</span> <span class="o">(</span><span class="n">I</span> <span class="n">j</span><span class="o">)</span> <span class="n">e</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">i</span> <span class="k">have</span> <span class="n">hI'</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">j</span> <span class="bp">∈</span> <span class="o">({</span><span class="n">i</span><span class="o">}</span> <span class="o">:</span> <span class="n">Finset</span> <span class="n">ι</span><span class="o">)</span><span class="bp">ᶜ</span><span class="o">,</span> <span class="n">IsCoprime</span> <span class="o">(</span><span class="n">I</span> <span class="n">i</span><span class="o">)</span> <span class="o">(</span><span class="n">I</span> <span class="n">j</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="gr">sorry</span> <span class="n">choose</span> <span class="n">e</span> <span class="n">he</span> <span class="n">using</span> <span class="n">key</span> <span class="n">use</span> <span class="n">mk</span> <span class="n">_</span> <span class="o">(</span><span class="bp">∑</span> <span class="n">i</span><span class="o">,</span> <span class="n">f</span> <span class="n">i</span> <span class="bp">*</span> <span class="n">e</span> <span class="n">i</span><span class="o">)</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">lemma</span><span class="w"> </span><span class="n">chineseMap_surj</span><span class="w"> </span><span class="o">[</span><span class="n">Fintype</span><span class="w"> </span><span class="n">ι</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">I</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Ideal</span><span class="w"> </span><span class="n">R</span><span class="o">}</span> <span class="w"> </span><span class="o">(</span><span class="n">hI</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="n">j</span><span class="o">,</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">IsCoprime</span><span class="w"> </span><span class="o">(</span><span class="n">I</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">I</span><span class="w"> </span><span class="n">j</span><span class="o">))</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Surjective</span><span class="w"> </span><span class="o">(</span><span class="n">chineseMap</span><span class="w"> </span><span class="n">I</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">classical</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">g</span> <span class="w"> </span><span class="n">choose</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">hf</span><span class="w"> </span><span class="n">using</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">Ideal.Quotient.mk_surjective</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="n">i</span><span class="o">)</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">key</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">,</span><span class="w"> </span><span class="n">mk</span><span class="w"> </span><span class="o">(</span><span class="n">I</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">j</span><span class="o">,</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">mk</span><span class="w"> </span><span class="o">(</span><span class="n">I</span><span class="w"> </span><span class="n">j</span><span class="o">)</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">i</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">hI'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="o">({</span><span class="n">i</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Finset</span><span class="w"> </span><span class="n">ι</span><span class="o">)</span><span class="bp">ᶜ</span><span class="o">,</span><span class="w"> </span><span class="n">IsCoprime</span><span class="w"> </span><span class="o">(</span><span class="n">I</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">I</span><span class="w"> </span><span class="n">j</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">choose</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="n">he</span><span class="w"> </span><span class="n">using</span><span class="w"> </span><span class="n">key</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">mk</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">(</span><span class="bp">∑</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="n">i</span><span class="o">)</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Now all the pieces come together in the following:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">noncomputable</span> <span class="kd">def</span> <span class="n">chineseIso</span> <span class="o">[</span><span class="n">Fintype</span> <span class="n">ι</span><span class="o">]</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">Ideal</span> <span class="n">R</span><span class="o">)</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">i</span> <span class="n">j</span><span class="o">,</span> <span class="n">i</span> <span class="bp">≠</span> <span class="n">j</span> <span class="bp">→</span> <span class="n">IsCoprime</span> <span class="o">(</span><span class="n">f</span> <span class="n">i</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="n">j</span><span class="o">))</span> <span class="o">:</span> <span class="o">(</span><span class="n">R</span> <span class="bp">⧸</span> <span class="bp">⨅</span> <span class="n">i</span><span class="o">,</span> <span class="n">f</span> <span class="n">i</span><span class="o">)</span> <span class="bp">≃+*</span> <span class="bp">Π</span> <span class="n">i</span><span class="o">,</span> <span class="n">R</span> <span class="bp">⧸</span> <span class="n">f</span> <span class="n">i</span> <span class="o">:=</span> <span class="o">{</span> <span class="n">Equiv.ofBijective</span> <span class="n">_</span> <span class="o">⟨</span><span class="n">chineseMap_inj</span> <span class="n">f</span><span class="o">,</span> <span class="n">chineseMap_surj</span> <span class="n">hf</span><span class="o">⟩,</span> <span class="n">chineseMap</span> <span class="n">f</span> <span class="k">with</span> <span class="o">}</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">noncomputable</span><span class="w"> </span><span class="kd">def</span><span class="w"> </span><span class="n">chineseIso</span><span class="w"> </span><span class="o">[</span><span class="n">Fintype</span><span class="w"> </span><span class="n">ι</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Ideal</span><span class="w"> </span><span class="n">R</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="n">j</span><span class="o">,</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">IsCoprime</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">j</span><span class="o">))</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">R</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="bp">⨅</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">≃+*</span><span class="w"> </span><span class="bp">Π</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">Equiv.ofBijective</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">⟨</span><span class="n">chineseMap_inj</span><span class="w"> </span><span class="n">f</span><span class="o">,</span><span class="w"> </span><span class="n">chineseMap_surj</span><span class="w"> </span><span class="n">hf</span><span class="o">⟩,</span> <span class="w"> </span><span class="n">chineseMap</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">}</span> </pre></div> </div> </section>
-
@@ -946,13 +947,13 @@ Note that this notion of algebra is sometimes called an <em>associative unital algebra</em> to emphasize theexistence of more general notions of algebra.</p> <p>The fact that <code class="docutils literal notranslate"><span class="pre">algebraMap</span> <span class="pre">R</span> <span class="pre">A</span></code> is ring morphism packages together a lot of properties of scalar multiplication, such as the following:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="n">A</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="o">[</span><span class="n">Ring</span> <span class="n">A</span><span class="o">]</span> <span class="o">[</span><span class="n">Algebra</span> <span class="n">R</span> <span class="n">A</span><span class="o">]</span> <span class="o">(</span><span class="n">r</span> <span class="n">r'</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">A</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">r</span> <span class="bp">+</span> <span class="n">r'</span><span class="o">)</span> <span class="bp">•</span> <span class="n">a</span> <span class="bp">=</span> <span class="n">r</span> <span class="bp">•</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">r'</span> <span class="bp">•</span> <span class="n">a</span> <span class="o">:=</span> <span class="n">add_smul</span> <span class="n">r</span> <span class="n">r'</span> <span class="n">a</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Ring</span><span class="w"> </span><span class="n">A</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Algebra</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="n">A</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="n">r'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">A</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">r'</span><span class="o">)</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">r'</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">add_smul</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="n">r'</span><span class="w"> </span><span class="n">a</span> <span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="n">A</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="o">[</span><span class="n">Ring</span> <span class="n">A</span><span class="o">]</span> <span class="o">[</span><span class="n">Algebra</span> <span class="n">R</span> <span class="n">A</span><span class="o">]</span> <span class="o">(</span><span class="n">r</span> <span class="n">r'</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">A</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">r</span> <span class="bp">*</span> <span class="n">r'</span><span class="o">)</span> <span class="bp">•</span> <span class="n">a</span> <span class="bp">=</span> <span class="n">r</span> <span class="bp">•</span> <span class="n">r'</span> <span class="bp">•</span> <span class="n">a</span> <span class="o">:=</span> <span class="n">mul_smul</span> <span class="n">r</span> <span class="n">r'</span> <span class="n">a</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Ring</span><span class="w"> </span><span class="n">A</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Algebra</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="n">A</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="n">r'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">A</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">r'</span><span class="o">)</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">r'</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">mul_smul</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="n">r'</span><span class="w"> </span><span class="n">a</span> </pre></div> </div> <p>The morphisms between two <code class="docutils literal notranslate"><span class="pre">R</span></code>-algebras <code class="docutils literal notranslate"><span class="pre">A</span></code> and <code class="docutils literal notranslate"><span class="pre">B</span></code> are ring morphisms
-
@@ -967,11 +968,11 @@ which can be written as <code class="docutils literal notranslate"><span class="pre">R[X]</span></code> as soon as one opens the <code class="docutils literal notranslate"><span class="pre">Polynomial</span></code> namespace.The algebra structure map from <code class="docutils literal notranslate"><span class="pre">R</span></code> to <code class="docutils literal notranslate"><span class="pre">R[X]</span></code> is denoted by <code class="docutils literal notranslate"><span class="pre">C</span></code>, which stands for “constant” since the corresponding polynomial functions are always constant. The indeterminate is denoted by <code class="docutils literal notranslate"><span class="pre">X</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">Polynomial</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">Polynomial</span> <span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="o">:</span> <span class="n">R</span><span class="o">[</span><span class="n">X</span><span class="o">]</span> <span class="o">:=</span> <span class="n">X</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">[</span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">X</span> <span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="o">(</span><span class="n">r</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">:=</span> <span class="n">X</span> <span class="bp">-</span> <span class="n">C</span> <span class="n">r</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">C</span><span class="w"> </span><span class="n">r</span> </pre></div> </div> <p>In the first example above, it is crucial that we give Lean the expected type since it cannot be
-
@@ -980,15 +981,15 @@ algebra can be inferred from our use of <code class="docutils literal notranslate"><span class="pre">C</span> <span class="pre">r</span></code> since the type of <code class="docutils literal notranslate"><span class="pre">r</span></code> is known.</p><p>Because <code class="docutils literal notranslate"><span class="pre">C</span></code> is a ring morphism from <code class="docutils literal notranslate"><span class="pre">R</span></code> to <code class="docutils literal notranslate"><span class="pre">R[X]</span></code>, we can use all ring morphisms lemmas such as <code class="docutils literal notranslate"><span class="pre">map_zero</span></code>, <code class="docutils literal notranslate"><span class="pre">map_one</span></code>, <code class="docutils literal notranslate"><span class="pre">map_mul</span></code>, and <code class="docutils literal notranslate"><span class="pre">map_pow</span></code> before computing in the ring <code class="docutils literal notranslate"><span class="pre">R[X]</span></code>. For example:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="o">(</span><span class="n">r</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">X</span> <span class="bp">+</span> <span class="n">C</span> <span class="n">r</span><span class="o">)</span> <span class="bp">*</span> <span class="o">(</span><span class="n">X</span> <span class="bp">-</span> <span class="n">C</span> <span class="n">r</span><span class="o">)</span> <span class="bp">=</span> <span class="n">X</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">-</span> <span class="n">C</span> <span class="o">(</span><span class="n">r</span> <span class="bp">^</span> <span class="mi">2</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">C.map_pow</span><span class="o">]</span> <span class="n">ring</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">X</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">C</span><span class="w"> </span><span class="n">r</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">X</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">C</span><span class="w"> </span><span class="n">r</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">C</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">C.map_pow</span><span class="o">]</span> <span class="w"> </span><span class="n">ring</span> </pre></div> </div> <p>You can access coefficients using <code class="docutils literal notranslate"><span class="pre">Polynomial.coeff</span></code></p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="o">(</span><span class="n">r</span><span class="o">:</span><span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">C</span> <span class="n">r</span><span class="o">)</span><span class="bp">.</span><span class="n">coeff</span> <span class="mi">0</span> <span class="bp">=</span> <span class="n">r</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="o">:</span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">C</span><span class="w"> </span><span class="n">r</span><span class="o">)</span><span class="bp">.</span><span class="n">coeff</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simp</span> <span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="o">:</span> <span class="o">(</span><span class="n">X</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="mi">2</span> <span class="bp">*</span> <span class="n">X</span> <span class="bp">+</span> <span class="n">C</span> <span class="mi">3</span> <span class="o">:</span> <span class="n">R</span><span class="o">[</span><span class="n">X</span><span class="o">])</span><span class="bp">.</span><span class="n">coeff</span> <span class="mi">1</span> <span class="bp">=</span> <span class="mi">2</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">X</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">C</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">[</span><span class="n">X</span><span class="o">])</span><span class="bp">.</span><span class="n">coeff</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simp</span> </pre></div> </div> <p>Defining the degree of a polynomial is always tricky because of the special case of the zero
-
@@ -1000,36 +1001,36 @@ degree of the zero polynomial, and it is absorbent for addition. (It is almost absorbent formultiplication, except that <code class="docutils literal notranslate"><span class="pre">⊥</span> <span class="pre">*</span> <span class="pre">0</span> <span class="pre">=</span> <span class="pre">0</span></code>.)</p> <p>Morally speaking, the <code class="docutils literal notranslate"><span class="pre">degree</span></code> version is the correct one. For instance, it allows us to state the expected formula for the degree of a product (assuming the base ring has no zero divisor).</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Semiring</span> <span class="n">R</span><span class="o">]</span> <span class="o">[</span><span class="n">NoZeroDivisors</span> <span class="n">R</span><span class="o">]</span> <span class="o">{</span><span class="n">p</span> <span class="n">q</span> <span class="o">:</span> <span class="n">R</span><span class="o">[</span><span class="n">X</span><span class="o">]}</span> <span class="o">:</span> <span class="n">degree</span> <span class="o">(</span><span class="n">p</span> <span class="bp">*</span> <span class="n">q</span><span class="o">)</span> <span class="bp">=</span> <span class="n">degree</span> <span class="n">p</span> <span class="bp">+</span> <span class="n">degree</span> <span class="n">q</span> <span class="o">:=</span> <span class="n">Polynomial.degree_mul</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Semiring</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">NoZeroDivisors</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">p</span><span class="w"> </span><span class="n">q</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">[</span><span class="n">X</span><span class="o">]}</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">degree</span><span class="w"> </span><span class="o">(</span><span class="n">p</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">q</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">degree</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">degree</span><span class="w"> </span><span class="n">q</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Polynomial.degree_mul</span> </pre></div> </div> <p>Whereas the version for <code class="docutils literal notranslate"><span class="pre">natDegree</span></code> needs to assume non-zero polynomials.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Semiring</span> <span class="n">R</span><span class="o">]</span> <span class="o">[</span><span class="n">NoZeroDivisors</span> <span class="n">R</span><span class="o">]</span> <span class="o">{</span><span class="n">p</span> <span class="n">q</span> <span class="o">:</span> <span class="n">R</span><span class="o">[</span><span class="n">X</span><span class="o">]}</span> <span class="o">(</span><span class="n">hp</span> <span class="o">:</span> <span class="n">p</span> <span class="bp">≠</span> <span class="mi">0</span><span class="o">)</span> <span class="o">(</span><span class="n">hq</span> <span class="o">:</span> <span class="n">q</span> <span class="bp">≠</span> <span class="mi">0</span><span class="o">)</span> <span class="o">:</span> <span class="n">natDegree</span> <span class="o">(</span><span class="n">p</span> <span class="bp">*</span> <span class="n">q</span><span class="o">)</span> <span class="bp">=</span> <span class="n">natDegree</span> <span class="n">p</span> <span class="bp">+</span> <span class="n">natDegree</span> <span class="n">q</span> <span class="o">:=</span> <span class="n">Polynomial.natDegree_mul</span> <span class="n">hp</span> <span class="n">hq</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Semiring</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">NoZeroDivisors</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">p</span><span class="w"> </span><span class="n">q</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">[</span><span class="n">X</span><span class="o">]}</span><span class="w"> </span><span class="o">(</span><span class="n">hp</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hq</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">q</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">natDegree</span><span class="w"> </span><span class="o">(</span><span class="n">p</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">q</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">natDegree</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">natDegree</span><span class="w"> </span><span class="n">q</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Polynomial.natDegree_mul</span><span class="w"> </span><span class="n">hp</span><span class="w"> </span><span class="n">hq</span> </pre></div> </div> <p>However, <code class="docutils literal notranslate"><span class="pre">ℕ</span></code> is much nicer to use than <code class="docutils literal notranslate"><span class="pre">WithBot</span> <span class="pre">ℕ</span></code>, so Mathlib makes both versions available and provides lemmas to convert between them. Also, <code class="docutils literal notranslate"><span class="pre">natDegree</span></code> is the more convenient definition to use when computing the degree of a composition. Composition of polynomial is <code class="docutils literal notranslate"><span class="pre">Polynomial.comp</span></code> and we have:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Semiring</span> <span class="n">R</span><span class="o">]</span> <span class="o">[</span><span class="n">NoZeroDivisors</span> <span class="n">R</span><span class="o">]</span> <span class="o">{</span><span class="n">p</span> <span class="n">q</span> <span class="o">:</span> <span class="n">R</span><span class="o">[</span><span class="n">X</span><span class="o">]}</span> <span class="o">:</span> <span class="n">natDegree</span> <span class="o">(</span><span class="n">comp</span> <span class="n">p</span> <span class="n">q</span><span class="o">)</span> <span class="bp">=</span> <span class="n">natDegree</span> <span class="n">p</span> <span class="bp">*</span> <span class="n">natDegree</span> <span class="n">q</span> <span class="o">:=</span> <span class="n">Polynomial.natDegree_comp</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Semiring</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">NoZeroDivisors</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">p</span><span class="w"> </span><span class="n">q</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">[</span><span class="n">X</span><span class="o">]}</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">natDegree</span><span class="w"> </span><span class="o">(</span><span class="n">comp</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="n">q</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">natDegree</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">natDegree</span><span class="w"> </span><span class="n">q</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Polynomial.natDegree_comp</span> </pre></div> </div> <p>Polynomials give rise to polynomial functions: any polynomial can be evaluated on <code class="docutils literal notranslate"><span class="pre">R</span></code> using <code class="docutils literal notranslate"><span class="pre">Polynomial.eval</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="o">(</span><span class="n">P</span><span class="o">:</span> <span class="n">R</span><span class="o">[</span><span class="n">X</span><span class="o">])</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">:=</span> <span class="n">P.eval</span> <span class="n">x</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">P</span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">[</span><span class="n">X</span><span class="o">])</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">P.eval</span><span class="w"> </span><span class="n">x</span> <span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="o">(</span><span class="n">r</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">X</span> <span class="bp">-</span> <span class="n">C</span> <span class="n">r</span><span class="o">)</span><span class="bp">.</span><span class="n">eval</span> <span class="n">r</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">X</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">C</span><span class="w"> </span><span class="n">r</span><span class="o">)</span><span class="bp">.</span><span class="n">eval</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simp</span> </pre></div> </div> <p>In particular, there is a predicate, <code class="docutils literal notranslate"><span class="pre">IsRoot</span></code>, that holds for elements <code class="docutils literal notranslate"><span class="pre">r</span></code> in <code class="docutils literal notranslate"><span class="pre">R</span></code> where a polynomial vanishes.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="o">(</span><span class="n">P</span> <span class="o">:</span> <span class="n">R</span><span class="o">[</span><span class="n">X</span><span class="o">])</span> <span class="o">(</span><span class="n">r</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="n">IsRoot</span> <span class="n">P</span> <span class="n">r</span> <span class="bp">↔</span> <span class="n">P.eval</span> <span class="n">r</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="n">Iff.rfl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">P</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">[</span><span class="n">X</span><span class="o">])</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsRoot</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">P.eval</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Iff.rfl</span> </pre></div> </div> <p>We would like to say that, assuming <code class="docutils literal notranslate"><span class="pre">R</span></code> has no zero divisor, a polynomial has at most as many
-
@@ -1039,12 +1040,12 @@ So Mathlib defines <code class="docutils literal notranslate"><span class="pre">Polynomial.roots</span></code> to send a polynomial <code class="docutils literal notranslate"><span class="pre">P</span></code> to a multiset,i.e. the finite set that is defined to be empty if <code class="docutils literal notranslate"><span class="pre">P</span></code> is zero and the roots of <code class="docutils literal notranslate"><span class="pre">P</span></code>, with multiplicities, otherwise. This is defined only when the underlying ring is a domain since otherwise the definition does not have good properties.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="o">[</span><span class="n">IsDomain</span> <span class="n">R</span><span class="o">]</span> <span class="o">(</span><span class="n">r</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">X</span> <span class="bp">-</span> <span class="n">C</span> <span class="n">r</span><span class="o">)</span><span class="bp">.</span><span class="n">roots</span> <span class="bp">=</span> <span class="o">{</span><span class="n">r</span><span class="o">}</span> <span class="o">:=</span> <span class="n">roots_X_sub_C</span> <span class="n">r</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">IsDomain</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">X</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">C</span><span class="w"> </span><span class="n">r</span><span class="o">)</span><span class="bp">.</span><span class="n">roots</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">{</span><span class="n">r</span><span class="o">}</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">roots_X_sub_C</span><span class="w"> </span><span class="n">r</span> <span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommRing</span> <span class="n">R</span><span class="o">]</span> <span class="o">[</span><span class="n">IsDomain</span> <span class="n">R</span><span class="o">]</span> <span class="o">(</span><span class="n">r</span> <span class="o">:</span> <span class="n">R</span><span class="o">)</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">):</span> <span class="o">((</span><span class="n">X</span> <span class="bp">-</span> <span class="n">C</span> <span class="n">r</span><span class="o">)</span> <span class="bp">^</span> <span class="n">n</span><span class="o">)</span><span class="bp">.</span><span class="n">roots</span> <span class="bp">=</span> <span class="n">n</span> <span class="bp">•</span> <span class="o">{</span><span class="n">r</span><span class="o">}</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommRing</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">IsDomain</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">):</span> <span class="w"> </span><span class="o">((</span><span class="n">X</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">C</span><span class="w"> </span><span class="n">r</span><span class="o">)</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="bp">.</span><span class="n">roots</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="o">{</span><span class="n">r</span><span class="o">}</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simp</span> </pre></div> </div> <p>Both <code class="docutils literal notranslate"><span class="pre">Polynomial.eval</span></code> and <code class="docutils literal notranslate"><span class="pre">Polynomial.roots</span></code> consider only the coefficients ring. They do not
-
@@ -1055,38 +1056,38 @@ every element of <code class="docutils literal notranslate"><span class="pre">a</span></code> along the <code class="docutils literal notranslate"><span class="pre">R</span></code>-algebra morphism of evaluation at <code class="docutils literal notranslate"><span class="pre">a</span></code>. Since <code class="docutils literal notranslate"><span class="pre">AlgHom</span></code>has a coercion to functions, one can apply it to a polynomial. But <code class="docutils literal notranslate"><span class="pre">aeval</span></code> does not have a polynomial as an argument, so one cannot use dot notation like in <code class="docutils literal notranslate"><span class="pre">P.eval</span></code> above.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">aeval</span> <span class="n">Complex.I</span> <span class="o">(</span><span class="n">X</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="mi">1</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">[</span><span class="n">X</span><span class="o">])</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">aeval</span><span class="w"> </span><span class="n">Complex.I</span><span class="w"> </span><span class="o">(</span><span class="n">X</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">[</span><span class="n">X</span><span class="o">])</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simp</span> </pre></div> </div> <p>The function corresponding to <code class="docutils literal notranslate"><span class="pre">roots</span></code> in this context is <code class="docutils literal notranslate"><span class="pre">aroots</span></code> which takes a polynomial and then an algebra and outputs a multiset (with the same caveat about the zero polynomial as for <code class="docutils literal notranslate"><span class="pre">roots</span></code>).</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">Complex</span> <span class="n">Polynomial</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">Complex</span><span class="w"> </span><span class="n">Polynomial</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">aroots</span> <span class="o">(</span><span class="n">X</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="mi">1</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">[</span><span class="n">X</span><span class="o">])</span> <span class="n">ℂ</span> <span class="bp">=</span> <span class="o">{</span><span class="n">Complex.I</span><span class="o">,</span> <span class="bp">-</span><span class="n">I</span><span class="o">}</span> <span class="o">:=</span> <span class="kd">by</span> <span class="k">suffices</span> <span class="n">roots</span> <span class="o">(</span><span class="n">X</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="mi">1</span> <span class="o">:</span> <span class="n">ℂ</span><span class="o">[</span><span class="n">X</span><span class="o">])</span> <span class="bp">=</span> <span class="o">{</span><span class="n">I</span><span class="o">,</span> <span class="bp">-</span><span class="n">I</span><span class="o">}</span> <span class="kd">by</span> <span class="n">simpa</span> <span class="o">[</span><span class="n">aroots_def</span><span class="o">]</span> <span class="k">have</span> <span class="n">factored</span> <span class="o">:</span> <span class="o">(</span><span class="n">X</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="mi">1</span> <span class="o">:</span> <span class="n">ℂ</span><span class="o">[</span><span class="n">X</span><span class="o">])</span> <span class="bp">=</span> <span class="o">(</span><span class="n">X</span> <span class="bp">-</span> <span class="n">C</span> <span class="n">I</span><span class="o">)</span> <span class="bp">*</span> <span class="o">(</span><span class="n">X</span> <span class="bp">-</span> <span class="n">C</span> <span class="o">(</span><span class="bp">-</span><span class="n">I</span><span class="o">))</span> <span class="o">:=</span> <span class="kd">by</span> <span class="k">have</span> <span class="n">key</span> <span class="o">:</span> <span class="o">(</span><span class="n">C</span> <span class="n">I</span> <span class="bp">*</span> <span class="n">C</span> <span class="n">I</span> <span class="o">:</span> <span class="n">ℂ</span><span class="o">[</span><span class="n">X</span><span class="o">])</span> <span class="bp">=</span> <span class="bp">-</span><span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="o">[</span><span class="bp">←</span> <span class="n">C_mul</span><span class="o">]</span> <span class="n">rw</span> <span class="o">[</span><span class="n">C_neg</span><span class="o">]</span> <span class="n">linear_combination</span> <span class="n">key</span> <span class="k">have</span> <span class="n">p_ne_zero</span> <span class="o">:</span> <span class="o">(</span><span class="n">X</span> <span class="bp">-</span> <span class="n">C</span> <span class="n">I</span><span class="o">)</span> <span class="bp">*</span> <span class="o">(</span><span class="n">X</span> <span class="bp">-</span> <span class="n">C</span> <span class="o">(</span><span class="bp">-</span><span class="n">I</span><span class="o">))</span> <span class="bp">≠</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">H</span> <span class="n">apply_fun</span> <span class="n">eval</span> <span class="mi">0</span> <span class="n">at</span> <span class="n">H</span> <span class="n">simp</span> <span class="o">[</span><span class="n">eval</span><span class="o">]</span> <span class="n">at</span> <span class="n">H</span> <span class="n">simp</span> <span class="n">only</span> <span class="o">[</span><span class="n">factored</span><span class="o">,</span> <span class="n">roots_mul</span> <span class="n">p_ne_zero</span><span class="o">,</span> <span class="n">roots_X_sub_C</span><span class="o">]</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">aroots</span><span class="w"> </span><span class="o">(</span><span class="n">X</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">[</span><span class="n">X</span><span class="o">])</span><span class="w"> </span><span class="n">ℂ</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">{</span><span class="n">Complex.I</span><span class="o">,</span><span class="w"> </span><span class="bp">-</span><span class="n">I</span><span class="o">}</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="k">suffices</span><span class="w"> </span><span class="n">roots</span><span class="w"> </span><span class="o">(</span><span class="n">X</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℂ</span><span class="o">[</span><span class="n">X</span><span class="o">])</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">{</span><span class="n">I</span><span class="o">,</span><span class="w"> </span><span class="bp">-</span><span class="n">I</span><span class="o">}</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simpa</span><span class="w"> </span><span class="o">[</span><span class="n">aroots_def</span><span class="o">]</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">factored</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">X</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℂ</span><span class="o">[</span><span class="n">X</span><span class="o">])</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">X</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">C</span><span class="w"> </span><span class="n">I</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">X</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">C</span><span class="w"> </span><span class="o">(</span><span class="bp">-</span><span class="n">I</span><span class="o">))</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">key</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">C</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">C</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℂ</span><span class="o">[</span><span class="n">X</span><span class="o">])</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">-</span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="bp">←</span><span class="w"> </span><span class="n">C_mul</span><span class="o">]</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">C_neg</span><span class="o">]</span> <span class="w"> </span><span class="n">linear_combination</span><span class="w"> </span><span class="n">key</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">p_ne_zero</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">X</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">C</span><span class="w"> </span><span class="n">I</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">X</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">C</span><span class="w"> </span><span class="o">(</span><span class="bp">-</span><span class="n">I</span><span class="o">))</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">H</span> <span class="w"> </span><span class="n">apply_fun</span><span class="w"> </span><span class="n">eval</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">H</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">eval</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">H</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="n">only</span><span class="w"> </span><span class="o">[</span><span class="n">factored</span><span class="o">,</span><span class="w"> </span><span class="n">roots_mul</span><span class="w"> </span><span class="n">p_ne_zero</span><span class="o">,</span><span class="w"> </span><span class="n">roots_X_sub_C</span><span class="o">]</span> <span class="w"> </span><span class="n">rfl</span> <span class="c1">-- Mathlib knows about D'Alembert-Gauss theorem: ``ℂ`` is algebraically closed.</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">IsAlgClosed</span> <span class="n">ℂ</span> <span class="o">:=</span> <span class="n">inferInstance</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsAlgClosed</span><span class="w"> </span><span class="n">ℂ</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">inferInstance</span> </pre></div> </div> <p>More generally, given an ring morphism <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">:</span> <span class="pre">R</span> <span class="pre">→+*</span> <span class="pre">S</span></code> one can evaluate <code class="docutils literal notranslate"><span class="pre">P</span> <span class="pre">:</span> <span class="pre">R[X]</span></code> at a point in <code class="docutils literal notranslate"><span class="pre">S</span></code> using <code class="docutils literal notranslate"><span class="pre">Polynomial.eval₂</span></code>. This one produces an actual function from <code class="docutils literal notranslate"><span class="pre">R[X]</span></code> to <code class="docutils literal notranslate"><span class="pre">S</span></code> since it does not assume the existence of a <code class="docutils literal notranslate"><span class="pre">Algebra</span> <span class="pre">R</span> <span class="pre">S</span></code> instance, so dot notation works as you would expect.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="o">(</span><span class="n">Complex.ofRealHom</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→+*</span> <span class="n">ℂ</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">Complex.ofRealHom</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→+*</span><span class="w"> </span><span class="n">ℂ</span><span class="o">)</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">X</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="mi">1</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">[</span><span class="n">X</span><span class="o">])</span><span class="bp">.</span><span class="n">eval₂</span> <span class="n">Complex.ofRealHom</span> <span class="n">Complex.I</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">X</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">[</span><span class="n">X</span><span class="o">])</span><span class="bp">.</span><span class="n">eval₂</span><span class="w"> </span><span class="n">Complex.ofRealHom</span><span class="w"> </span><span class="n">Complex.I</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simp</span> </pre></div> </div> <p>Let us end by mentioning multivariate polynomials briefly. Given a commutative semiring <code class="docutils literal notranslate"><span class="pre">R</span></code>,
-
@@ -1096,9 +1097,9 @@ <code class="docutils literal notranslate"><span class="pre">MvPolynomial.X</span> <span class="pre">i</span></code>. (As usual, one can open the <code class="docutils literal notranslate"><span class="pre">MVPolynomial</span></code> namespace to shorten thisto <code class="docutils literal notranslate"><span class="pre">X</span> <span class="pre">i</span></code>.) For instance, if we want two indeterminates we can use <code class="docutils literal notranslate"><span class="pre">Fin</span> <span class="pre">2</span></code> as <code class="docutils literal notranslate"><span class="pre">σ</span></code> and write the polynomial defining the unit circle in <span class="math notranslate nohighlight">\(\mathbb{R}^2`\)</span> as:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">MvPolynomial</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">MvPolynomial</span> <span class="kd">def</span> <span class="n">circleEquation</span> <span class="o">:</span> <span class="n">MvPolynomial</span> <span class="o">(</span><span class="n">Fin</span> <span class="mi">2</span><span class="o">)</span> <span class="n">ℝ</span> <span class="o">:=</span> <span class="n">X</span> <span class="mi">0</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="n">X</span> <span class="mi">1</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">-</span> <span class="mi">1</span> <span class="kd">def</span><span class="w"> </span><span class="n">circleEquation</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MvPolynomial</span><span class="w"> </span><span class="o">(</span><span class="n">Fin</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="mi">1</span> </pre></div> </div> <p>Recall that function application has a very high precedence so the expression above is read as
-
@@ -1106,7 +1107,7 @@ <code class="docutils literal notranslate"><span class="pre">(X</span> <span class="pre">0)</span> <span class="pre">^</span> <span class="pre">2</span> <span class="pre">+</span> <span class="pre">(X</span> <span class="pre">1)</span> <span class="pre">^</span> <span class="pre">2</span> <span class="pre">-</span> <span class="pre">1</span></code>.We can evaluate it to make sure the point with coordinates <span class="math notranslate nohighlight">\((1, 0)\)</span> is on the circle. Recall the <code class="docutils literal notranslate"><span class="pre">![...]</span></code> notation denotes elements of <code class="docutils literal notranslate"><span class="pre">Fin</span> <span class="pre">n</span> <span class="pre">→</span> <span class="pre">X</span></code> for some natural number <code class="docutils literal notranslate"><span class="pre">n</span></code> determined by the number of arguments and some type <code class="docutils literal notranslate"><span class="pre">X</span></code> determined by the type of arguments.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">MvPolynomial.eval</span> <span class="bp">!</span><span class="o">[</span><span class="mi">0</span><span class="o">,</span> <span class="mi">1</span><span class="o">]</span> <span class="n">circleEquation</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="o">[</span><span class="n">circleEquation</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MvPolynomial.eval</span><span class="w"> </span><span class="bp">!</span><span class="o">[</span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span><span class="o">]</span><span class="w"> </span><span class="n">circleEquation</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">circleEquation</span><span class="o">]</span> </pre></div> </div> </section>
-
-
-
@@ -1,3 +1,5 @@<!DOCTYPE html> <html class="writer-html5" lang="en" data-content_root="./"> <head>
-
@@ -6,18 +8,17 @@<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>9. Linear algebra — Mathematics in Lean 0.1 documentation</title> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=80d5e7a1" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=86f27845" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" /> <link rel="stylesheet" type="text/css" href="_static/css/custom.css?v=0731ccc3" /> <link rel="shortcut icon" href="_static/favicon.ico"/> <script src="_static/jquery.js?v=8dae8fb0"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=888ff710"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> <script src="_static/jquery.js?v=5d32c60e"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=9bcbadda"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> <script src="_static/js/theme.js"></script> <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" />
-
@@ -122,7 +123,7 @@ Mathlib actually deals with a more general version of linear algebra involving the word module,but for now we will pretend this is only an eccentric spelling habit.</p> <p>The way to say “let <span class="math notranslate nohighlight">\(K\)</span> be a field and let <span class="math notranslate nohighlight">\(V\)</span> be a vector space over <span class="math notranslate nohighlight">\(K\)</span>” (and make them implicit arguments to later results) is:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">K</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Field</span> <span class="n">K</span><span class="o">]</span> <span class="o">{</span><span class="n">V</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">AddCommGroup</span> <span class="n">V</span><span class="o">]</span> <span class="o">[</span><span class="n">Module</span> <span class="n">K</span> <span class="n">V</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">K</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Field</span><span class="w"> </span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">V</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">AddCommGroup</span><span class="w"> </span><span class="n">V</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Module</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">]</span> </pre></div> </div> <p>We explained in <a class="reference internal" href="C07_Hierarchies.html#hierarchies"><span class="std std-numref">Chapter 7</span></a> why we need two separate
-
@@ -143,14 +144,14 @@ following from the axioms of vector spaces and fields, in the same way the<cite>ring</cite> tactic is used in commutative rings or the <cite>group</cite> tactic is used in groups. But it is still useful to remember that scalar multiplication is abbreviated <cite>smul</cite> in lemma names.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">K</span><span class="o">)</span> <span class="o">(</span><span class="n">u</span> <span class="n">v</span> <span class="o">:</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">•</span> <span class="o">(</span><span class="n">u</span> <span class="bp">+</span> <span class="n">v</span><span class="o">)</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">•</span> <span class="n">u</span> <span class="bp">+</span> <span class="n">a</span> <span class="bp">•</span> <span class="n">v</span> <span class="o">:=</span> <span class="n">smul_add</span> <span class="n">a</span> <span class="n">u</span> <span class="n">v</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">v</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">smul_add</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">v</span> <span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">K</span><span class="o">)</span> <span class="o">(</span><span class="n">u</span> <span class="o">:</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">a</span> <span class="bp">+</span> <span class="n">b</span><span class="o">)</span> <span class="bp">•</span> <span class="n">u</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">•</span> <span class="n">u</span> <span class="bp">+</span> <span class="n">b</span> <span class="bp">•</span> <span class="n">u</span> <span class="o">:=</span> <span class="n">add_smul</span> <span class="n">a</span> <span class="n">b</span> <span class="n">u</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">add_smul</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">u</span> <span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">K</span><span class="o">)</span> <span class="o">(</span><span class="n">u</span> <span class="o">:</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">•</span> <span class="n">b</span> <span class="bp">•</span> <span class="n">u</span> <span class="bp">=</span> <span class="n">b</span> <span class="bp">•</span> <span class="n">a</span> <span class="bp">•</span> <span class="n">u</span> <span class="o">:=</span> <span class="n">smul_comm</span> <span class="n">a</span> <span class="n">b</span> <span class="n">u</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">smul_comm</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">u</span> </pre></div> </div> <p>As a quick note for more advanced readers, let us point out that, as suggested by
-
@@ -159,9 +160,9 @@ rings.In fact it even covers semi-modules over semi-rings. If you think you do not need this level of generality, you can meditate the following example that nicely captures a lot of algebraic rules about ideals acting on submodules:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">R</span> <span class="n">M</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CommSemiring</span> <span class="n">R</span><span class="o">]</span> <span class="o">[</span><span class="n">AddCommMonoid</span> <span class="n">M</span><span class="o">]</span> <span class="o">[</span><span class="n">Module</span> <span class="n">R</span> <span class="n">M</span><span class="o">]</span> <span class="o">:</span> <span class="n">Module</span> <span class="o">(</span><span class="n">Ideal</span> <span class="n">R</span><span class="o">)</span> <span class="o">(</span><span class="n">Submodule</span> <span class="n">R</span> <span class="n">M</span><span class="o">)</span> <span class="o">:=</span> <span class="n">inferInstance</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">R</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CommSemiring</span><span class="w"> </span><span class="n">R</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">AddCommMonoid</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Module</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="n">M</span><span class="o">]</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Module</span><span class="w"> </span><span class="o">(</span><span class="n">Ideal</span><span class="w"> </span><span class="n">R</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">Submodule</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">inferInstance</span> </pre></div> </div> </section>
-
@@ -178,31 +179,31 @@ But this is crucial when several fields come into play.For instance real-linear maps from <span class="math notranslate nohighlight">\(ℂ\)</span> to <span class="math notranslate nohighlight">\(ℂ\)</span> are every map <span class="math notranslate nohighlight">\(z ↦ az + b\bar{z}\)</span> while only the maps <span class="math notranslate nohighlight">\(z ↦ az\)</span> are complex linear, and this difference is crucial in complex analysis.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">W</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">AddCommGroup</span> <span class="n">W</span><span class="o">]</span> <span class="o">[</span><span class="n">Module</span> <span class="n">K</span> <span class="n">W</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">W</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">AddCommGroup</span><span class="w"> </span><span class="n">W</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Module</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">W</span><span class="o">]</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="o">)</span> <span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">K</span><span class="o">)</span> <span class="o">(</span><span class="n">v</span> <span class="o">:</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="n">φ</span> <span class="o">(</span><span class="n">a</span> <span class="bp">•</span> <span class="n">v</span><span class="o">)</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">•</span> <span class="n">φ</span> <span class="n">v</span> <span class="o">:=</span> <span class="n">map_smul</span> <span class="n">φ</span> <span class="n">a</span> <span class="n">v</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">v</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">v</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">map_smul</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">v</span> <span class="kd">example</span> <span class="o">(</span><span class="n">v</span> <span class="n">w</span> <span class="o">:</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="n">φ</span> <span class="o">(</span><span class="n">v</span> <span class="bp">+</span> <span class="n">w</span><span class="o">)</span> <span class="bp">=</span> <span class="n">φ</span> <span class="n">v</span> <span class="bp">+</span> <span class="n">φ</span> <span class="n">w</span> <span class="o">:=</span> <span class="n">map_add</span> <span class="n">φ</span> <span class="n">v</span> <span class="n">w</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">v</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="o">(</span><span class="n">v</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">w</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">map_add</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="n">w</span> </pre></div> </div> <p>Note that <code class="docutils literal notranslate"><span class="pre">V</span> <span class="pre">→ₗ[K]</span> <span class="pre">W</span></code> itself carries interesting algebraic structures (this is part of the motivation for bundling those maps). It is a <code class="docutils literal notranslate"><span class="pre">K</span></code>-vector space so we can add linear maps and multiply them by scalars.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">(</span><span class="n">ψ</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">ψ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="mi">2</span> <span class="bp">•</span> <span class="n">φ</span> <span class="bp">+</span> <span class="n">ψ</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="mi">2</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">ψ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="o">)</span> </pre></div> </div> <p>One downside of using bundled maps is that we cannot use ordinary function composition. We need to use <code class="docutils literal notranslate"><span class="pre">LinearMap.comp</span></code> or the notation <code class="docutils literal notranslate"><span class="pre">∘ₗ</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">(</span><span class="n">θ</span> <span class="o">:</span> <span class="n">W</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">V</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">θ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">V</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">φ.comp</span> <span class="n">θ</span> <span class="o">:</span> <span class="n">W</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">φ</span> <span class="bp">∘ₗ</span> <span class="n">θ</span> <span class="o">:</span> <span class="n">W</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">φ.comp</span><span class="w"> </span><span class="n">θ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="bp">∘ₗ</span><span class="w"> </span><span class="n">θ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="o">)</span> </pre></div> </div> <p>There are two main ways to construct linear maps.
-
@@ -210,10 +211,10 @@ First we can build the structure by providing the function and the linearity proof.As usual, this is facilitated by the structure code action: you can type <code class="docutils literal notranslate"><span class="pre">example</span> <span class="pre">:</span> <span class="pre">V</span> <span class="pre">→ₗ[K]</span> <span class="pre">V</span> <span class="pre">:=</span> <span class="pre">_</span></code> and use the code action “Generate a skeleton” attached to the underscore.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">V</span> <span class="n">where</span> <span class="n">toFun</span> <span class="n">v</span> <span class="o">:=</span> <span class="mi">3</span> <span class="bp">•</span> <span class="n">v</span> <span class="n">map_add'</span> <span class="n">_</span> <span class="n">_</span> <span class="o">:=</span> <span class="n">smul_add</span> <span class="bp">..</span> <span class="n">map_smul'</span> <span class="n">_</span> <span class="n">_</span> <span class="o">:=</span> <span class="n">smul_comm</span> <span class="bp">..</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">v</span> <span class="w"> </span><span class="n">map_add'</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">smul_add</span><span class="w"> </span><span class="bp">..</span> <span class="w"> </span><span class="n">map_smul'</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">smul_comm</span><span class="w"> </span><span class="bp">..</span> </pre></div> </div> <p>You may wonder why the proof fields of <code class="docutils literal notranslate"><span class="pre">LinearMap</span></code> have names ending with a prime.
-
@@ -226,9 +227,9 @@ linear maps, <code class="docutils literal notranslate"><span class="pre">K</span></code>-algebra maps etc… This one is <code class="docutils literal notranslate"><span class="pre">map_add</span></code> (in the root namespace).The intermediate version, <code class="docutils literal notranslate"><span class="pre">LinearMap.map_add</span></code> is a bit redundant but allows to use dot notation, which can be nice sometimes. A similar story exists for <code class="docutils literal notranslate"><span class="pre">map_smul</span></code>, and the general framework is explained in <a class="reference internal" href="C07_Hierarchies.html#hierarchies"><span class="std std-numref">Chapter 7</span></a>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="o">(</span><span class="n">φ.map_add'</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">V</span><span class="o">,</span> <span class="n">φ.toFun</span> <span class="o">(</span><span class="n">x</span> <span class="bp">+</span> <span class="n">y</span><span class="o">)</span> <span class="bp">=</span> <span class="n">φ.toFun</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">φ.toFun</span> <span class="n">y</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">φ.map_add</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">V</span><span class="o">,</span> <span class="n">φ</span> <span class="o">(</span><span class="n">x</span> <span class="bp">+</span> <span class="n">y</span><span class="o">)</span> <span class="bp">=</span> <span class="n">φ</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">φ</span> <span class="n">y</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">map_add</span> <span class="n">φ</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">V</span><span class="o">,</span> <span class="n">φ</span> <span class="o">(</span><span class="n">x</span> <span class="bp">+</span> <span class="n">y</span><span class="o">)</span> <span class="bp">=</span> <span class="n">φ</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">φ</span> <span class="n">y</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">φ.map_add'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="o">,</span><span class="w"> </span><span class="n">φ.toFun</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">φ.toFun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">φ.toFun</span><span class="w"> </span><span class="n">y</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">φ.map_add</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="o">,</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">y</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">map_add</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="o">,</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">y</span><span class="o">)</span> </pre></div> </div> <p>One can also build linear maps from the ones that are already defined in Mathlib
-
@@ -240,8 +241,8 @@ for Lean to infer <code class="docutils literal notranslate"><span class="pre">V</span></code> or even <code class="docutils literal notranslate"><span class="pre">K</span></code>.But also <code class="docutils literal notranslate"><span class="pre">LinearMap.lsmul</span> <span class="pre">K</span> <span class="pre">V</span></code> is an interesting object by itself: it has type <code class="docutils literal notranslate"><span class="pre">K</span> <span class="pre">→ₗ[K]</span> <span class="pre">V</span> <span class="pre">→ₗ[K]</span> <span class="pre">V</span></code>, meaning it is a <code class="docutils literal notranslate"><span class="pre">K</span></code>-linear map from <code class="docutils literal notranslate"><span class="pre">K</span></code> —seen as a vector space over itself— to the space of <code class="docutils literal notranslate"><span class="pre">K</span></code>-linear maps from <code class="docutils literal notranslate"><span class="pre">V</span></code> to <code class="docutils literal notranslate"><span class="pre">V</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="o">(</span><span class="n">LinearMap.lsmul</span> <span class="n">K</span> <span class="n">V</span> <span class="mi">3</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">V</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">LinearMap.lsmul</span> <span class="n">K</span> <span class="n">V</span> <span class="o">:</span> <span class="n">K</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">V</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">LinearMap.lsmul</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">V</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">LinearMap.lsmul</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">V</span><span class="o">)</span> </pre></div> </div> <p>There is also a type <code class="docutils literal notranslate"><span class="pre">LinearEquiv</span></code> of linear isomorphisms denoted by <code class="docutils literal notranslate"><span class="pre">V</span> <span class="pre">≃ₗ[K]</span> <span class="pre">W</span></code>.
-
@@ -249,14 +250,14 @@ The inverse of <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">:</span> <span class="pre">V</span> <span class="pre">≃ₗ[K]</span> <span class="pre">W</span></code> is <code class="docutils literal notranslate"><span class="pre">f.symm</span> <span class="pre">:</span> <span class="pre">W</span> <span class="pre">≃ₗ[K]</span> <span class="pre">V</span></code>,composition of <code class="docutils literal notranslate"><span class="pre">f</span></code> and <code class="docutils literal notranslate"><span class="pre">g</span></code> is <code class="docutils literal notranslate"><span class="pre">f.trans</span> <span class="pre">g</span></code> also denoted by <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">≪≫ₗ</span> <span class="pre">g</span></code>, and the identity isomorphism of <code class="docutils literal notranslate"><span class="pre">V</span></code> is <code class="docutils literal notranslate"><span class="pre">LinearEquiv.refl</span> <span class="pre">K</span> <span class="pre">V</span></code>. Elements of this type are automatically coerced to morphisms and functions when necessary.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">≃ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span><span class="o">)</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">≪≫ₗ</span> <span class="n">f.symm</span> <span class="bp">=</span> <span class="n">LinearEquiv.refl</span> <span class="n">K</span> <span class="n">V</span> <span class="o">:=</span> <span class="n">f.self_trans_symm</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">≃ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">≪≫ₗ</span><span class="w"> </span><span class="n">f.symm</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">LinearEquiv.refl</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">f.self_trans_symm</span> </pre></div> </div> <p>One can use <code class="docutils literal notranslate"><span class="pre">LinearEquiv.ofBijective</span></code> to build an isomorphism from a bijective morphism. Doing so makes the inverse function noncomputable.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">noncomputable</span> <span class="kd">example</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">Function.Bijective</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">≃ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span> <span class="o">:=</span> <span class="bp">.</span><span class="n">ofBijective</span> <span class="n">f</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">noncomputable</span><span class="w"> </span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Function.Bijective</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">≃ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="bp">.</span><span class="n">ofBijective</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>Note that in the above example, Lean uses the announced type to understand that <code class="docutils literal notranslate"><span class="pre">.ofBijective</span></code>
-
@@ -273,57 +274,57 @@ and projections) as linear maps, as well as the universal properties constructing linear mapsinto products and out of sums (if you are not familiar with the category-theoretic distinction between sums and products, you can simply ignore the universal property vocabulary and focus on the types of the following examples).</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span> <span class="n">binary_product</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span><span class="w"> </span><span class="n">binary_product</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">W</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">AddCommGroup</span> <span class="n">W</span><span class="o">]</span> <span class="o">[</span><span class="n">Module</span> <span class="n">K</span> <span class="n">W</span><span class="o">]</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">U</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">AddCommGroup</span> <span class="n">U</span><span class="o">]</span> <span class="o">[</span><span class="n">Module</span> <span class="n">K</span> <span class="n">U</span><span class="o">]</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">T</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">AddCommGroup</span> <span class="n">T</span><span class="o">]</span> <span class="o">[</span><span class="n">Module</span> <span class="n">K</span> <span class="n">T</span><span class="o">]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">W</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">AddCommGroup</span><span class="w"> </span><span class="n">W</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Module</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">W</span><span class="o">]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">U</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">AddCommGroup</span><span class="w"> </span><span class="n">U</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Module</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">U</span><span class="o">]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">T</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">AddCommGroup</span><span class="w"> </span><span class="n">T</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Module</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">T</span><span class="o">]</span> <span class="c1">-- First projection map</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">×</span> <span class="n">W</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">V</span> <span class="o">:=</span> <span class="n">LinearMap.fst</span> <span class="n">K</span> <span class="n">V</span> <span class="n">W</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">LinearMap.fst</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">W</span> <span class="c1">-- Second projection map</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">×</span> <span class="n">W</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span> <span class="o">:=</span> <span class="n">LinearMap.snd</span> <span class="n">K</span> <span class="n">V</span> <span class="n">W</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">LinearMap.snd</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">W</span> <span class="c1">-- Universal property of the product</span> <span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">U</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">V</span><span class="o">)</span> <span class="o">(</span><span class="n">ψ</span> <span class="o">:</span> <span class="n">U</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span><span class="o">)</span> <span class="o">:</span> <span class="n">U</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">V</span> <span class="bp">×</span> <span class="n">W</span> <span class="o">:=</span> <span class="n">LinearMap.prod</span> <span class="n">φ</span> <span class="n">ψ</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ψ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">LinearMap.prod</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">ψ</span> <span class="c1">-- The product map does the expected thing, first component</span> <span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">U</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">V</span><span class="o">)</span> <span class="o">(</span><span class="n">ψ</span> <span class="o">:</span> <span class="n">U</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span><span class="o">)</span> <span class="o">:</span> <span class="n">LinearMap.fst</span> <span class="n">K</span> <span class="n">V</span> <span class="n">W</span> <span class="bp">∘ₗ</span> <span class="n">LinearMap.prod</span> <span class="n">φ</span> <span class="n">ψ</span> <span class="bp">=</span> <span class="n">φ</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ψ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">LinearMap.fst</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="bp">∘ₗ</span><span class="w"> </span><span class="n">LinearMap.prod</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">ψ</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">rfl</span> <span class="c1">-- The product map does the expected thing, second component</span> <span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">U</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">V</span><span class="o">)</span> <span class="o">(</span><span class="n">ψ</span> <span class="o">:</span> <span class="n">U</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span><span class="o">)</span> <span class="o">:</span> <span class="n">LinearMap.snd</span> <span class="n">K</span> <span class="n">V</span> <span class="n">W</span> <span class="bp">∘ₗ</span> <span class="n">LinearMap.prod</span> <span class="n">φ</span> <span class="n">ψ</span> <span class="bp">=</span> <span class="n">ψ</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ψ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">LinearMap.snd</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="bp">∘ₗ</span><span class="w"> </span><span class="n">LinearMap.prod</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">ψ</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">ψ</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">rfl</span> <span class="c1">-- We can also combine maps in parallel</span> <span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">U</span><span class="o">)</span> <span class="o">(</span><span class="n">ψ</span> <span class="o">:</span> <span class="n">W</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">T</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">V</span> <span class="bp">×</span> <span class="n">W</span><span class="o">)</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="o">(</span><span class="n">U</span> <span class="bp">×</span> <span class="n">T</span><span class="o">)</span> <span class="o">:=</span> <span class="n">φ.prodMap</span> <span class="n">ψ</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">U</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ψ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">T</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">V</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">W</span><span class="o">)</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">U</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">T</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">φ.prodMap</span><span class="w"> </span><span class="n">ψ</span> <span class="c1">-- This is simply done by combining the projections with the universal property</span> <span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">U</span><span class="o">)</span> <span class="o">(</span><span class="n">ψ</span> <span class="o">:</span> <span class="n">W</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">T</span><span class="o">)</span> <span class="o">:</span> <span class="n">φ.prodMap</span> <span class="n">ψ</span> <span class="bp">=</span> <span class="o">(</span><span class="n">φ</span> <span class="bp">∘ₗ</span> <span class="bp">.</span><span class="n">fst</span> <span class="n">K</span> <span class="n">V</span> <span class="n">W</span><span class="o">)</span><span class="bp">.</span><span class="n">prod</span> <span class="o">(</span><span class="n">ψ</span> <span class="bp">∘ₗ</span> <span class="bp">.</span><span class="n">snd</span> <span class="n">K</span> <span class="n">V</span> <span class="n">W</span><span class="o">)</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">U</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ψ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">T</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">φ.prodMap</span><span class="w"> </span><span class="n">ψ</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="bp">∘ₗ</span><span class="w"> </span><span class="bp">.</span><span class="n">fst</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">W</span><span class="o">)</span><span class="bp">.</span><span class="n">prod</span><span class="w"> </span><span class="o">(</span><span class="n">ψ</span><span class="w"> </span><span class="bp">∘ₗ</span><span class="w"> </span><span class="bp">.</span><span class="n">snd</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">W</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">rfl</span> <span class="c1">-- First inclusion map</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">V</span> <span class="bp">×</span> <span class="n">W</span> <span class="o">:=</span> <span class="n">LinearMap.inl</span> <span class="n">K</span> <span class="n">V</span> <span class="n">W</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">LinearMap.inl</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">W</span> <span class="c1">-- Second inclusion map</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">W</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">V</span> <span class="bp">×</span> <span class="n">W</span> <span class="o">:=</span> <span class="n">LinearMap.inr</span> <span class="n">K</span> <span class="n">V</span> <span class="n">W</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">LinearMap.inr</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">W</span> <span class="c1">-- Universal property of the sum (aka coproduct)</span> <span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">U</span><span class="o">)</span> <span class="o">(</span><span class="n">ψ</span> <span class="o">:</span> <span class="n">W</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">U</span><span class="o">)</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">×</span> <span class="n">W</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">U</span> <span class="o">:=</span> <span class="n">φ.coprod</span> <span class="n">ψ</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">U</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ψ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">U</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">φ.coprod</span><span class="w"> </span><span class="n">ψ</span> <span class="c1">-- The coproduct map does the expected thing, first component</span> <span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">U</span><span class="o">)</span> <span class="o">(</span><span class="n">ψ</span> <span class="o">:</span> <span class="n">W</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">U</span><span class="o">)</span> <span class="o">:</span> <span class="n">φ.coprod</span> <span class="n">ψ</span> <span class="bp">∘ₗ</span> <span class="n">LinearMap.inl</span> <span class="n">K</span> <span class="n">V</span> <span class="n">W</span> <span class="bp">=</span> <span class="n">φ</span> <span class="o">:=</span> <span class="n">LinearMap.coprod_inl</span> <span class="n">φ</span> <span class="n">ψ</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">U</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ψ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">U</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">φ.coprod</span><span class="w"> </span><span class="n">ψ</span><span class="w"> </span><span class="bp">∘ₗ</span><span class="w"> </span><span class="n">LinearMap.inl</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">LinearMap.coprod_inl</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">ψ</span> <span class="c1">-- The coproduct map does the expected thing, second component</span> <span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">U</span><span class="o">)</span> <span class="o">(</span><span class="n">ψ</span> <span class="o">:</span> <span class="n">W</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">U</span><span class="o">)</span> <span class="o">:</span> <span class="n">φ.coprod</span> <span class="n">ψ</span> <span class="bp">∘ₗ</span> <span class="n">LinearMap.inr</span> <span class="n">K</span> <span class="n">V</span> <span class="n">W</span> <span class="bp">=</span> <span class="n">ψ</span> <span class="o">:=</span> <span class="n">LinearMap.coprod_inr</span> <span class="n">φ</span> <span class="n">ψ</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">U</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ψ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">U</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">φ.coprod</span><span class="w"> </span><span class="n">ψ</span><span class="w"> </span><span class="bp">∘ₗ</span><span class="w"> </span><span class="n">LinearMap.inr</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">ψ</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">LinearMap.coprod_inr</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">ψ</span> <span class="c1">-- The coproduct map is defined in the expected way</span> <span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">U</span><span class="o">)</span> <span class="o">(</span><span class="n">ψ</span> <span class="o">:</span> <span class="n">W</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">U</span><span class="o">)</span> <span class="o">(</span><span class="n">v</span> <span class="o">:</span> <span class="n">V</span><span class="o">)</span> <span class="o">(</span><span class="n">w</span> <span class="o">:</span> <span class="n">W</span><span class="o">)</span> <span class="o">:</span> <span class="n">φ.coprod</span> <span class="n">ψ</span> <span class="o">(</span><span class="n">v</span><span class="o">,</span> <span class="n">w</span><span class="o">)</span> <span class="bp">=</span> <span class="n">φ</span> <span class="n">v</span> <span class="bp">+</span> <span class="n">ψ</span> <span class="n">w</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">U</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ψ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">U</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">v</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">w</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">W</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">φ.coprod</span><span class="w"> </span><span class="n">ψ</span><span class="w"> </span><span class="o">(</span><span class="n">v</span><span class="o">,</span><span class="w"> </span><span class="n">w</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">ψ</span><span class="w"> </span><span class="n">w</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">end</span> <span class="n">binary_product</span> <span class="kd">end</span><span class="w"> </span><span class="n">binary_product</span> </pre></div> </div> <p>Let us now turn to sums and products of arbitrary families of vector spaces.
-
@@ -332,36 +333,36 @@ properties of sums and products.Note that the direct sum notation is scoped to the <code class="docutils literal notranslate"><span class="pre">DirectSum</span></code> namespace, and that the universal property of direct sums requires decidable equality on the indexing type (this is somehow an implementation accident).</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span> <span class="n">families</span> <span class="kn">open</span> <span class="n">DirectSum</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span><span class="w"> </span><span class="n">families</span> <span class="kn">open</span><span class="w"> </span><span class="n">DirectSum</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">ι</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">DecidableEq</span> <span class="n">ι</span><span class="o">]</span> <span class="o">(</span><span class="n">V</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">)</span> <span class="o">[</span><span class="bp">∀</span> <span class="n">i</span><span class="o">,</span> <span class="n">AddCommGroup</span> <span class="o">(</span><span class="n">V</span> <span class="n">i</span><span class="o">)]</span> <span class="o">[</span><span class="bp">∀</span> <span class="n">i</span><span class="o">,</span> <span class="n">Module</span> <span class="n">K</span> <span class="o">(</span><span class="n">V</span> <span class="n">i</span><span class="o">)]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">ι</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">DecidableEq</span><span class="w"> </span><span class="n">ι</span><span class="o">]</span> <span class="w"> </span><span class="o">(</span><span class="n">V</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="bp">∀</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">AddCommGroup</span><span class="w"> </span><span class="o">(</span><span class="n">V</span><span class="w"> </span><span class="n">i</span><span class="o">)]</span><span class="w"> </span><span class="o">[</span><span class="bp">∀</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">Module</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="o">(</span><span class="n">V</span><span class="w"> </span><span class="n">i</span><span class="o">)]</span> <span class="c1">-- The universal property of the direct sum assembles maps from the summands to build</span> <span class="c1">-- a map from the direct sum</span> <span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="bp">Π</span> <span class="n">i</span><span class="o">,</span> <span class="o">(</span><span class="n">V</span> <span class="n">i</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span><span class="o">))</span> <span class="o">:</span> <span class="o">(</span><span class="bp">⨁</span> <span class="n">i</span><span class="o">,</span> <span class="n">V</span> <span class="n">i</span><span class="o">)</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span> <span class="o">:=</span> <span class="n">DirectSum.toModule</span> <span class="n">K</span> <span class="n">ι</span> <span class="n">W</span> <span class="n">φ</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">Π</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="o">(</span><span class="n">V</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="o">))</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">⨁</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">DirectSum.toModule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="n">φ</span> <span class="c1">-- The universal property of the direct product assembles maps into the factors</span> <span class="c1">-- to build a map into the direct product</span> <span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="bp">Π</span> <span class="n">i</span><span class="o">,</span> <span class="o">(</span><span class="n">W</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">V</span> <span class="n">i</span><span class="o">))</span> <span class="o">:</span> <span class="n">W</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="o">(</span><span class="bp">Π</span> <span class="n">i</span><span class="o">,</span> <span class="n">V</span> <span class="n">i</span><span class="o">)</span> <span class="o">:=</span> <span class="n">LinearMap.pi</span> <span class="n">φ</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">Π</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="o">(</span><span class="n">W</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">i</span><span class="o">))</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="bp">Π</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">LinearMap.pi</span><span class="w"> </span><span class="n">φ</span> <span class="c1">-- The projection maps from the product</span> <span class="kd">example</span> <span class="o">(</span><span class="n">i</span> <span class="o">:</span> <span class="n">ι</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="bp">Π</span> <span class="n">j</span><span class="o">,</span> <span class="n">V</span> <span class="n">j</span><span class="o">)</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">V</span> <span class="n">i</span> <span class="o">:=</span> <span class="n">LinearMap.proj</span> <span class="n">i</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">i</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">Π</span><span class="w"> </span><span class="n">j</span><span class="o">,</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">j</span><span class="o">)</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">LinearMap.proj</span><span class="w"> </span><span class="n">i</span> <span class="c1">-- The inclusion maps into the sum</span> <span class="kd">example</span> <span class="o">(</span><span class="n">i</span> <span class="o">:</span> <span class="n">ι</span><span class="o">)</span> <span class="o">:</span> <span class="n">V</span> <span class="n">i</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="o">(</span><span class="bp">⨁</span> <span class="n">i</span><span class="o">,</span> <span class="n">V</span> <span class="n">i</span><span class="o">)</span> <span class="o">:=</span> <span class="n">DirectSum.lof</span> <span class="n">K</span> <span class="n">ι</span> <span class="n">V</span> <span class="n">i</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">i</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="bp">⨁</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">DirectSum.lof</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">i</span> <span class="c1">-- The inclusion maps into the product</span> <span class="kd">example</span> <span class="o">(</span><span class="n">i</span> <span class="o">:</span> <span class="n">ι</span><span class="o">)</span> <span class="o">:</span> <span class="n">V</span> <span class="n">i</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="o">(</span><span class="bp">Π</span> <span class="n">i</span><span class="o">,</span> <span class="n">V</span> <span class="n">i</span><span class="o">)</span> <span class="o">:=</span> <span class="n">LinearMap.single</span> <span class="n">K</span> <span class="n">V</span> <span class="n">i</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">i</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="bp">Π</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">LinearMap.single</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">i</span> <span class="c1">-- In case `ι` is a finite type, there is an isomorphism between the sum and product.</span> <span class="kd">example</span> <span class="o">[</span><span class="n">Fintype</span> <span class="n">ι</span><span class="o">]</span> <span class="o">:</span> <span class="o">(</span><span class="bp">⨁</span> <span class="n">i</span><span class="o">,</span> <span class="n">V</span> <span class="n">i</span><span class="o">)</span> <span class="bp">≃ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="o">(</span><span class="bp">Π</span> <span class="n">i</span><span class="o">,</span> <span class="n">V</span> <span class="n">i</span><span class="o">)</span> <span class="o">:=</span> <span class="n">linearEquivFunOnFintype</span> <span class="n">K</span> <span class="n">ι</span> <span class="n">V</span> <span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">Fintype</span><span class="w"> </span><span class="n">ι</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">⨁</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">≃ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="bp">Π</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">linearEquivFunOnFintype</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="n">V</span> <span class="kd">end</span> <span class="n">families</span> <span class="kd">end</span><span class="w"> </span><span class="n">families</span> </pre></div> </div> </section>
-
@@ -374,15 +375,15 @@ <p>Just as linear maps are bundled, a linear subspace of <code class="docutils literal notranslate"><span class="pre">V</span></code> is also a bundled structure consisting ofa set in <code class="docutils literal notranslate"><span class="pre">V</span></code>, called the carrier of the subspace, with the relevant closure properties. Again the word module appears instead of vector space because of the more general context that Mathlib actually uses for linear algebra.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">K</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Field</span> <span class="n">K</span><span class="o">]</span> <span class="o">{</span><span class="n">V</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">AddCommGroup</span> <span class="n">V</span><span class="o">]</span> <span class="o">[</span><span class="n">Module</span> <span class="n">K</span> <span class="n">V</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">K</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Field</span><span class="w"> </span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">V</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">AddCommGroup</span><span class="w"> </span><span class="n">V</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Module</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">]</span> <span class="kd">example</span> <span class="o">(</span><span class="n">U</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">{</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">V</span><span class="o">}</span> <span class="o">(</span><span class="n">hx</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">U</span><span class="o">)</span> <span class="o">(</span><span class="n">hy</span> <span class="o">:</span> <span class="n">y</span> <span class="bp">∈</span> <span class="n">U</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">y</span> <span class="bp">∈</span> <span class="n">U</span> <span class="o">:=</span> <span class="n">U.add_mem</span> <span class="n">hx</span> <span class="n">hy</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">U</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hx</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">U</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hy</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">U</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">U.add_mem</span><span class="w"> </span><span class="n">hx</span><span class="w"> </span><span class="n">hy</span> <span class="kd">example</span> <span class="o">(</span><span class="n">U</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">V</span><span class="o">}</span> <span class="o">(</span><span class="n">hx</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">U</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">K</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">•</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">U</span> <span class="o">:=</span> <span class="n">U.smul_mem</span> <span class="n">a</span> <span class="n">hx</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">U</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hx</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">U</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">U.smul_mem</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">hx</span> </pre></div> </div> <p>In the example above, it is important to understand that <code class="docutils literal notranslate"><span class="pre">Submodule</span> <span class="pre">K</span> <span class="pre">V</span></code> is the type of <code class="docutils literal notranslate"><span class="pre">K</span></code>-linear
-
@@ -395,19 +396,19 @@ equal in the same way it is used to prove that two sets are equal.</p><p>To state and prove, for example, that <code class="docutils literal notranslate"><span class="pre">ℝ</span></code> is a <code class="docutils literal notranslate"><span class="pre">ℝ</span></code>-linear subspace of <code class="docutils literal notranslate"><span class="pre">ℂ</span></code>, what we really want is to construct a term of type <code class="docutils literal notranslate"><span class="pre">Submodule</span> <span class="pre">ℝ</span> <span class="pre">ℂ</span></code> whose projection to <code class="docutils literal notranslate"><span class="pre">Set</span> <span class="pre">ℂ</span></code> is <code class="docutils literal notranslate"><span class="pre">ℝ</span></code>, or, more precisely, the image of <code class="docutils literal notranslate"><span class="pre">ℝ</span></code> in <code class="docutils literal notranslate"><span class="pre">ℂ</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">noncomputable</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">ℝ</span> <span class="n">ℂ</span> <span class="n">where</span> <span class="n">carrier</span> <span class="o">:=</span> <span class="n">Set.range</span> <span class="o">((</span><span class="bp">↑</span><span class="o">)</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℂ</span><span class="o">)</span> <span class="n">add_mem'</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rintro</span> <span class="n">_</span> <span class="n">_</span> <span class="o">⟨</span><span class="n">n</span><span class="o">,</span> <span class="n">rfl</span><span class="o">⟩</span> <span class="o">⟨</span><span class="n">m</span><span class="o">,</span> <span class="n">rfl</span><span class="o">⟩</span> <span class="n">use</span> <span class="n">n</span> <span class="bp">+</span> <span class="n">m</span> <span class="n">simp</span> <span class="n">zero_mem'</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">use</span> <span class="mi">0</span> <span class="n">simp</span> <span class="n">smul_mem'</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rintro</span> <span class="n">c</span> <span class="bp">-</span> <span class="o">⟨</span><span class="n">a</span><span class="o">,</span> <span class="n">rfl</span><span class="o">⟩</span> <span class="n">use</span> <span class="n">c</span><span class="bp">*</span><span class="n">a</span> <span class="n">simp</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">noncomputable</span><span class="w"> </span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="n">ℂ</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">carrier</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Set.range</span><span class="w"> </span><span class="o">((</span><span class="bp">↑</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℂ</span><span class="o">)</span> <span class="w"> </span><span class="n">add_mem'</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">⟨</span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">rfl</span><span class="o">⟩</span><span class="w"> </span><span class="o">⟨</span><span class="n">m</span><span class="o">,</span><span class="w"> </span><span class="n">rfl</span><span class="o">⟩</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">m</span> <span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="n">zero_mem'</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="mi">0</span> <span class="w"> </span><span class="n">simp</span> <span class="w"> </span><span class="n">smul_mem'</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="o">⟨</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">rfl</span><span class="o">⟩</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">c</span><span class="bp">*</span><span class="n">a</span> <span class="w"> </span><span class="n">simp</span> </pre></div> </div> <p>The prime at the end of proof fields in <code class="docutils literal notranslate"><span class="pre">Submodule</span></code> are analogous to the one in <code class="docutils literal notranslate"><span class="pre">LinearMap</span></code>.
-
@@ -419,27 +420,27 @@ a subspace by a linear map (of course we will see below that Mathlib already knows about this).Remember that <code class="docutils literal notranslate"><span class="pre">Set.mem_preimage</span></code> can be used to rewrite a statement involving membership and preimage. This is the only lemma you will need in addition to the lemmas discussed above about <code class="docutils literal notranslate"><span class="pre">LinearMap</span></code> and <code class="docutils literal notranslate"><span class="pre">Submodule</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">preimage</span> <span class="o">{</span><span class="n">W</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">AddCommGroup</span> <span class="n">W</span><span class="o">]</span> <span class="o">[</span><span class="n">Module</span> <span class="n">K</span> <span class="n">W</span><span class="o">]</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span><span class="o">)</span> <span class="o">(</span><span class="n">H</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">W</span><span class="o">)</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span> <span class="n">where</span> <span class="n">carrier</span> <span class="o">:=</span> <span class="n">φ</span> <span class="bp">⁻¹'</span> <span class="n">H</span> <span class="n">zero_mem'</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">dsimp</span> <span class="gr">sorry</span> <span class="n">add_mem'</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="n">smul_mem'</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">dsimp</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">preimage</span><span class="w"> </span><span class="o">{</span><span class="n">W</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">AddCommGroup</span><span class="w"> </span><span class="n">W</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Module</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">W</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">W</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">carrier</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="n">H</span> <span class="w"> </span><span class="n">zero_mem'</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">dsimp</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">add_mem'</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">smul_mem'</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">dsimp</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Using type classes, Mathlib knows that a subspace of a vector space inherits a vector space structure.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">U</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="n">Module</span> <span class="n">K</span> <span class="n">U</span> <span class="o">:=</span> <span class="n">inferInstance</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">U</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Module</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">inferInstance</span> </pre></div> </div> <p>This example is subtle. The object <code class="docutils literal notranslate"><span class="pre">U</span></code> is not a type, but Lean automatically coerces it to a type by interpreting it as a subtype of <code class="docutils literal notranslate"><span class="pre">V</span></code>. So the above example can be restated more explicitly as:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">U</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="n">Module</span> <span class="n">K</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">//</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">U</span><span class="o">}</span> <span class="o">:=</span> <span class="n">inferInstance</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">U</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Module</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">//</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">U</span><span class="o">}</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">inferInstance</span> </pre></div> </div> </section>
-
@@ -454,8 +455,8 @@ use the lattice operation <code class="docutils literal notranslate"><span class="pre">⊓</span></code> to construct the intersection. We can then apply arbitrarylemmas about lattices to the construction.</p> <p>Let us check that the set underlying the infimum of two subspaces is indeed, by definition, their intersection.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">H</span> <span class="n">H'</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="o">((</span><span class="n">H</span> <span class="bp">⊓</span> <span class="n">H'</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">V</span><span class="o">)</span> <span class="bp">=</span> <span class="o">(</span><span class="n">H</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">V</span><span class="o">)</span> <span class="bp">∩</span> <span class="o">(</span><span class="n">H'</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">V</span><span class="o">)</span> <span class="o">:=</span> <span class="n">rfl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">H</span><span class="w"> </span><span class="n">H'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="o">((</span><span class="n">H</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">H'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="o">(</span><span class="n">H'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">rfl</span> </pre></div> </div> <p>It may look strange to have a different notation for what amounts to the intersection of the
-
@@ -463,21 +464,21 @@ underlying sets, but the correspondence does not carry over to the supremum operation and setunion, since a union of subspaces is not, in general, a subspace. Instead one needs to use the subspace generated by the union, which is done using <code class="docutils literal notranslate"><span class="pre">Submodule.span</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">H</span> <span class="n">H'</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="o">((</span><span class="n">H</span> <span class="bp">⊔</span> <span class="n">H'</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">V</span><span class="o">)</span> <span class="bp">=</span> <span class="n">Submodule.span</span> <span class="n">K</span> <span class="o">((</span><span class="n">H</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">V</span><span class="o">)</span> <span class="bp">∪</span> <span class="o">(</span><span class="n">H'</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">V</span><span class="o">))</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="o">[</span><span class="n">Submodule.span_union</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">H</span><span class="w"> </span><span class="n">H'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="o">((</span><span class="n">H</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">H'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">Submodule.span</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="o">((</span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="bp">∪</span><span class="w"> </span><span class="o">(</span><span class="n">H'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">V</span><span class="o">))</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">simp</span><span class="w"> </span><span class="o">[</span><span class="n">Submodule.span_union</span><span class="o">]</span> </pre></div> </div> <p>Another subtlety is that <code class="docutils literal notranslate"><span class="pre">V</span></code> itself does not have type <code class="docutils literal notranslate"><span class="pre">Submodule</span> <span class="pre">K</span> <span class="pre">V</span></code>, so we need a way to talk about <code class="docutils literal notranslate"><span class="pre">V</span></code> seen as a subspace of <code class="docutils literal notranslate"><span class="pre">V</span></code>. This is also provided by the lattice structure: the full subspace is the top element of this lattice.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∈</span> <span class="o">(</span><span class="bp">⊤</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">:=</span> <span class="n">trivial</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="o">(</span><span class="bp">⊤</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">trivial</span> </pre></div> </div> <p>Similarly the bottom element of this lattice is the subspace whose only element is the zero element.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∈</span> <span class="o">(</span><span class="bp">⊥</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="bp">↔</span> <span class="n">x</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="n">Submodule.mem_bot</span> <span class="n">K</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="o">(</span><span class="bp">⊥</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Submodule.mem_bot</span><span class="w"> </span><span class="n">K</span> </pre></div> </div> <p>In particular we can discuss the case of subspaces that are in (internal) direct sum.
-
@@ -485,35 +486,35 @@ In the case of two subspaces, we use the general purpose predicate <code class="docutils literal notranslate"><span class="pre">IsCompl</span></code>which makes sense for any bounded partially ordered type. In the case of general families of subspaces we use <code class="docutils literal notranslate"><span class="pre">DirectSum.IsInternal</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="c1">-- If two subspaces are in direct sum then they span the whole space.</span> <span class="kd">example</span> <span class="o">(</span><span class="n">U</span> <span class="n">V</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">IsCompl</span> <span class="n">U</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="n">U</span> <span class="bp">⊔</span> <span class="n">V</span> <span class="bp">=</span> <span class="bp">⊤</span> <span class="o">:=</span> <span class="n">h.sup_eq_top</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">U</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsCompl</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">⊤</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">h.sup_eq_top</span> <span class="c1">-- If two subspaces are in direct sum then they intersect only at zero.</span> <span class="kd">example</span> <span class="o">(</span><span class="n">U</span> <span class="n">V</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">IsCompl</span> <span class="n">U</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="n">U</span> <span class="bp">⊓</span> <span class="n">V</span> <span class="bp">=</span> <span class="bp">⊥</span> <span class="o">:=</span> <span class="n">h.inf_eq_bot</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">U</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsCompl</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">⊥</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">h.inf_eq_bot</span> <span class="kn">section</span> <span class="kn">open</span> <span class="n">DirectSum</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">ι</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">DecidableEq</span> <span class="n">ι</span><span class="o">]</span> <span class="kn">open</span><span class="w"> </span><span class="n">DirectSum</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">ι</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">DecidableEq</span><span class="w"> </span><span class="n">ι</span><span class="o">]</span> <span class="c1">-- If subspaces are in direct sum then they span the whole space.</span> <span class="kd">example</span> <span class="o">(</span><span class="n">U</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">DirectSum.IsInternal</span> <span class="n">U</span><span class="o">)</span> <span class="o">:</span> <span class="bp">⨆</span> <span class="n">i</span><span class="o">,</span> <span class="n">U</span> <span class="n">i</span> <span class="bp">=</span> <span class="bp">⊤</span> <span class="o">:=</span> <span class="n">h.submodule_iSup_eq_top</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">U</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">DirectSum.IsInternal</span><span class="w"> </span><span class="n">U</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">⨆</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">⊤</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">h.submodule_iSup_eq_top</span> <span class="c1">-- If subspaces are in direct sum then they pairwise intersect only at zero.</span> <span class="kd">example</span> <span class="o">{</span><span class="n">ι</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">DecidableEq</span> <span class="n">ι</span><span class="o">]</span> <span class="o">(</span><span class="n">U</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">DirectSum.IsInternal</span> <span class="n">U</span><span class="o">)</span> <span class="o">{</span><span class="n">i</span> <span class="n">j</span> <span class="o">:</span> <span class="n">ι</span><span class="o">}</span> <span class="o">(</span><span class="n">hij</span> <span class="o">:</span> <span class="n">i</span> <span class="bp">≠</span> <span class="n">j</span><span class="o">)</span> <span class="o">:</span> <span class="n">U</span> <span class="n">i</span> <span class="bp">⊓</span> <span class="n">U</span> <span class="n">j</span> <span class="bp">=</span> <span class="bp">⊥</span> <span class="o">:=</span> <span class="o">(</span><span class="n">h.submodule_independent.pairwiseDisjoint</span> <span class="n">hij</span><span class="o">)</span><span class="bp">.</span><span class="n">eq_bot</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">ι</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">DecidableEq</span><span class="w"> </span><span class="n">ι</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">U</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">DirectSum.IsInternal</span><span class="w"> </span><span class="n">U</span><span class="o">)</span> <span class="w"> </span><span class="o">{</span><span class="n">i</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hij</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="n">j</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">⊥</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">(</span><span class="n">h.submodule_independent.pairwiseDisjoint</span><span class="w"> </span><span class="n">hij</span><span class="o">)</span><span class="bp">.</span><span class="n">eq_bot</span> <span class="c1">-- Those conditions characterize direct sums.</span> <span class="k">#check</span> <span class="n">DirectSum.isInternal_submodule_iff_independent_and_iSup_eq_top</span> <span class="k">#check</span><span class="w"> </span><span class="n">DirectSum.isInternal_submodule_iff_independent_and_iSup_eq_top</span> <span class="c1">-- The relation with external direct sums: if a family of subspaces is</span> <span class="c1">-- in internal direct sum then the map from their external direct sum into `V`</span> <span class="c1">-- is a linear isomorphism.</span> <span class="kd">noncomputable</span> <span class="kd">example</span> <span class="o">{</span><span class="n">ι</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">DecidableEq</span> <span class="n">ι</span><span class="o">]</span> <span class="o">(</span><span class="n">U</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">DirectSum.IsInternal</span> <span class="n">U</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="bp">⨁</span> <span class="n">i</span><span class="o">,</span> <span class="n">U</span> <span class="n">i</span><span class="o">)</span> <span class="bp">≃ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">V</span> <span class="o">:=</span> <span class="n">LinearEquiv.ofBijective</span> <span class="o">(</span><span class="n">coeLinearMap</span> <span class="n">U</span><span class="o">)</span> <span class="n">h</span> <span class="kd">noncomputable</span><span class="w"> </span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">ι</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">DecidableEq</span><span class="w"> </span><span class="n">ι</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">U</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">DirectSum.IsInternal</span><span class="w"> </span><span class="n">U</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">⨁</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">≃ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">LinearEquiv.ofBijective</span><span class="w"> </span><span class="o">(</span><span class="n">coeLinearMap</span><span class="w"> </span><span class="n">U</span><span class="o">)</span><span class="w"> </span><span class="n">h</span> <span class="kd">end</span> </pre></div> </div>
-
@@ -527,11 +528,11 @@ On paper it is common to use that this space is made of all linear combinations of elements of<code class="docutils literal notranslate"><span class="pre">s</span></code>. But it is often more efficient to use its universal property expressed by <code class="docutils literal notranslate"><span class="pre">Submodule.span_le</span></code>, and the whole theory of Galois connections.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">V</span><span class="o">}</span> <span class="o">(</span><span class="n">E</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="n">Submodule.span</span> <span class="n">K</span> <span class="n">s</span> <span class="bp">≤</span> <span class="n">E</span> <span class="bp">↔</span> <span class="n">s</span> <span class="bp">⊆</span> <span class="n">E</span> <span class="o">:=</span> <span class="n">Submodule.span_le</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">V</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">E</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule.span</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Submodule.span_le</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">GaloisInsertion</span> <span class="o">(</span><span class="n">Submodule.span</span> <span class="n">K</span><span class="o">)</span> <span class="o">((</span><span class="bp">↑</span><span class="o">)</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span> <span class="bp">→</span> <span class="n">Set</span> <span class="n">V</span><span class="o">)</span> <span class="o">:=</span> <span class="n">Submodule.gi</span> <span class="n">K</span> <span class="n">V</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">GaloisInsertion</span><span class="w"> </span><span class="o">(</span><span class="n">Submodule.span</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="o">((</span><span class="bp">↑</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Submodule.gi</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span> </pre></div> </div> <p>When those are not enough, one can use the relevant induction principle
-
@@ -541,18 +542,18 @@ sum and scalar multiplication.</p><p>As an exercise, let us reprove one implication of <code class="docutils literal notranslate"><span class="pre">Submodule.mem_sup</span></code>. Remember that you can use the <cite>module</cite> tactic to close goals that follow from the axioms relating the various algebraic operations on <code class="docutils literal notranslate"><span class="pre">V</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">S</span> <span class="n">T</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">}</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">V</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">S</span> <span class="bp">⊔</span> <span class="n">T</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">s</span> <span class="bp">∈</span> <span class="n">S</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">t</span> <span class="bp">∈</span> <span class="n">T</span><span class="o">,</span> <span class="n">x</span> <span class="bp">=</span> <span class="n">s</span> <span class="bp">+</span> <span class="n">t</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="bp">←</span> <span class="n">S.span_eq</span><span class="o">,</span> <span class="bp">←</span> <span class="n">T.span_eq</span><span class="o">,</span> <span class="bp">←</span> <span class="n">Submodule.span_union</span><span class="o">]</span> <span class="n">at</span> <span class="n">h</span> <span class="n">induction</span> <span class="n">h</span> <span class="n">using</span> <span class="n">Submodule.span_induction</span> <span class="k">with</span> <span class="bp">|</span> <span class="n">mem</span> <span class="n">y</span> <span class="n">h</span> <span class="bp">=></span> <span class="gr">sorry</span> <span class="bp">|</span> <span class="n">zero</span> <span class="bp">=></span> <span class="gr">sorry</span> <span class="bp">|</span> <span class="n">add</span> <span class="n">x</span> <span class="n">y</span> <span class="n">hx</span> <span class="n">hy</span> <span class="n">hx'</span> <span class="n">hy'</span> <span class="bp">=></span> <span class="gr">sorry</span> <span class="bp">|</span> <span class="n">smul</span> <span class="n">a</span> <span class="n">x</span> <span class="n">hx</span> <span class="n">hx'</span> <span class="bp">=></span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">S</span><span class="w"> </span><span class="n">T</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">T</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">S</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">T</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="bp">←</span><span class="w"> </span><span class="n">S.span_eq</span><span class="o">,</span><span class="w"> </span><span class="bp">←</span><span class="w"> </span><span class="n">T.span_eq</span><span class="o">,</span><span class="w"> </span><span class="bp">←</span><span class="w"> </span><span class="n">Submodule.span_union</span><span class="o">]</span><span class="w"> </span><span class="n">at</span><span class="w"> </span><span class="n">h</span> <span class="w"> </span><span class="n">induction</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="n">using</span><span class="w"> </span><span class="n">Submodule.span_induction</span><span class="w"> </span><span class="k">with</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">mem</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="bp">=></span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">zero</span><span class="w"> </span><span class="bp">=></span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">add</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">hx</span><span class="w"> </span><span class="n">hy</span><span class="w"> </span><span class="n">hx'</span><span class="w"> </span><span class="n">hy'</span><span class="w"> </span><span class="bp">=></span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">smul</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">hx</span><span class="w"> </span><span class="n">hx'</span><span class="w"> </span><span class="bp">=></span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> </section>
-
@@ -563,13 +564,13 @@ As usual in Mathlib, the first operation is called <code class="docutils literal notranslate"><span class="pre">map</span></code> and the second one is called<code class="docutils literal notranslate"><span class="pre">comap</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">W</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">AddCommGroup</span> <span class="n">W</span><span class="o">]</span> <span class="o">[</span><span class="n">Module</span> <span class="n">K</span> <span class="n">W</span><span class="o">]</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">W</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">AddCommGroup</span><span class="w"> </span><span class="n">W</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Module</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">W</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="o">)</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">E</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="k">in</span> <span class="k">#check</span> <span class="o">(</span><span class="n">Submodule.map</span> <span class="n">φ</span> <span class="n">E</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">W</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">E</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="k">in</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">Submodule.map</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">W</span><span class="o">)</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">F</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">W</span><span class="o">)</span> <span class="k">in</span> <span class="k">#check</span> <span class="o">(</span><span class="n">Submodule.comap</span> <span class="n">φ</span> <span class="n">F</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">W</span><span class="o">)</span><span class="w"> </span><span class="k">in</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">Submodule.comap</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span> </pre></div> </div> <p>Note those live in the <code class="docutils literal notranslate"><span class="pre">Submodule</span></code> namespace so one can use dot notation and write
-
@@ -577,9 +578,9 @@ <code class="docutils literal notranslate"><span class="pre">E.map</span> <span class="pre">φ</span></code> instead of <code class="docutils literal notranslate"><span class="pre">Submodule.map</span> <span class="pre">φ</span> <span class="pre">E</span></code>, but this is pretty awkward to read (although someMathlib contributors use this spelling).</p> <p>In particular the range and kernel of a linear map are subspaces. Those special cases are important enough to get declarations.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">LinearMap.range</span> <span class="n">φ</span> <span class="bp">=</span> <span class="bp">.</span><span class="n">map</span> <span class="n">φ</span> <span class="bp">⊤</span> <span class="o">:=</span> <span class="n">LinearMap.range_eq_map</span> <span class="n">φ</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">LinearMap.range</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">.</span><span class="n">map</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="bp">⊤</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">LinearMap.range_eq_map</span><span class="w"> </span><span class="n">φ</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">LinearMap.ker</span> <span class="n">φ</span> <span class="bp">=</span> <span class="bp">.</span><span class="n">comap</span> <span class="n">φ</span> <span class="bp">⊥</span> <span class="o">:=</span> <span class="n">Submodule.comap_bot</span> <span class="n">φ</span> <span class="c1">-- or `rfl`</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">LinearMap.ker</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">.</span><span class="n">comap</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="bp">⊥</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Submodule.comap_bot</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="c1">-- or `rfl`</span> </pre></div> </div> <p>Note that we cannot write <code class="docutils literal notranslate"><span class="pre">φ.ker</span></code> instead of <code class="docutils literal notranslate"><span class="pre">LinearMap.ker</span> <span class="pre">φ</span></code> because <code class="docutils literal notranslate"><span class="pre">LinearMap.ker</span></code> also
-
@@ -589,22 +590,22 @@ However we were able to use the other flavor of dot notation in the right-hand side. BecauseLean expects a term with type <code class="docutils literal notranslate"><span class="pre">Submodule</span> <span class="pre">K</span> <span class="pre">V</span></code> after elaborating the left-hand side, it interprets <code class="docutils literal notranslate"><span class="pre">.comap</span></code> as <code class="docutils literal notranslate"><span class="pre">Submodule.comap</span></code>.</p> <p>The following lemmas give the key relations between those submodule and the properties of <code class="docutils literal notranslate"><span class="pre">φ</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">Function</span> <span class="n">LinearMap</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">Function</span><span class="w"> </span><span class="n">LinearMap</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">Injective</span> <span class="n">φ</span> <span class="bp">↔</span> <span class="n">ker</span> <span class="n">φ</span> <span class="bp">=</span> <span class="bp">⊥</span> <span class="o">:=</span> <span class="n">ker_eq_bot.symm</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Injective</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">ker</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">⊥</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">ker_eq_bot.symm</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">Surjective</span> <span class="n">φ</span> <span class="bp">↔</span> <span class="n">range</span> <span class="n">φ</span> <span class="bp">=</span> <span class="bp">⊤</span> <span class="o">:=</span> <span class="n">range_eq_top.symm</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Surjective</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">range</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">⊤</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">range_eq_top.symm</span> </pre></div> </div> <p>As an exercise, let us prove the Galois connection property for <code class="docutils literal notranslate"><span class="pre">map</span></code> and <code class="docutils literal notranslate"><span class="pre">comap</span></code>. One can use the following lemmas but this is not required since they are true by definition.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="n">Submodule.mem_map_of_mem</span> <span class="k">#check</span> <span class="n">Submodule.mem_map</span> <span class="k">#check</span> <span class="n">Submodule.mem_comap</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="n">Submodule.mem_map_of_mem</span> <span class="k">#check</span><span class="w"> </span><span class="n">Submodule.mem_map</span> <span class="k">#check</span><span class="w"> </span><span class="n">Submodule.mem_comap</span> <span class="kd">example</span> <span class="o">(</span><span class="n">E</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">(</span><span class="n">F</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">W</span><span class="o">)</span> <span class="o">:</span> <span class="n">Submodule.map</span> <span class="n">φ</span> <span class="n">E</span> <span class="bp">≤</span> <span class="n">F</span> <span class="bp">↔</span> <span class="n">E</span> <span class="bp">≤</span> <span class="n">Submodule.comap</span> <span class="n">φ</span> <span class="n">F</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">E</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">W</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Submodule.map</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">Submodule.comap</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> </section>
-
@@ -614,35 +615,35 @@ <p>Quotient vector spaces use the general quotient notation (typed with <code class="docutils literal notranslate"><span class="pre">\quot</span></code>, not the ordinary<code class="docutils literal notranslate"><span class="pre">/</span></code>). The projection onto a quotient space is <code class="docutils literal notranslate"><span class="pre">Submodule.mkQ</span></code> and the universal property is <code class="docutils literal notranslate"><span class="pre">Submodule.liftQ</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">(</span><span class="n">E</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">E</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">Module</span> <span class="n">K</span> <span class="o">(</span><span class="n">V</span> <span class="bp">⧸</span> <span class="n">E</span><span class="o">)</span> <span class="o">:=</span> <span class="n">inferInstance</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Module</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="o">(</span><span class="n">V</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">E</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">inferInstance</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">V</span> <span class="bp">⧸</span> <span class="n">E</span> <span class="o">:=</span> <span class="n">E.mkQ</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">E.mkQ</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">ker</span> <span class="n">E.mkQ</span> <span class="bp">=</span> <span class="n">E</span> <span class="o">:=</span> <span class="n">E.ker_mkQ</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ker</span><span class="w"> </span><span class="n">E.mkQ</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">E.ker_mkQ</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">range</span> <span class="n">E.mkQ</span> <span class="bp">=</span> <span class="bp">⊤</span> <span class="o">:=</span> <span class="n">E.range_mkQ</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">range</span><span class="w"> </span><span class="n">E.mkQ</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">⊤</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">E.range_mkQ</span> <span class="kd">example</span> <span class="o">(</span><span class="n">hφ</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">≤</span> <span class="n">ker</span> <span class="n">φ</span><span class="o">)</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">⧸</span> <span class="n">E</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span> <span class="o">:=</span> <span class="n">E.liftQ</span> <span class="n">φ</span> <span class="n">hφ</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">hφ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">ker</span><span class="w"> </span><span class="n">φ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">E.liftQ</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">hφ</span> <span class="kd">example</span> <span class="o">(</span><span class="n">F</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">W</span><span class="o">)</span> <span class="o">(</span><span class="n">hφ</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">≤</span> <span class="bp">.</span><span class="n">comap</span> <span class="n">φ</span> <span class="n">F</span><span class="o">)</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">⧸</span> <span class="n">E</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span> <span class="bp">⧸</span> <span class="n">F</span> <span class="o">:=</span> <span class="n">E.mapQ</span> <span class="n">F</span> <span class="n">φ</span> <span class="n">hφ</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">W</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hφ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="bp">.</span><span class="n">comap</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">E.mapQ</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">hφ</span> <span class="kd">noncomputable</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="n">V</span> <span class="bp">⧸</span> <span class="n">LinearMap.ker</span> <span class="n">φ</span><span class="o">)</span> <span class="bp">≃ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">range</span> <span class="n">φ</span> <span class="o">:=</span> <span class="n">φ.quotKerEquivRange</span> <span class="kd">noncomputable</span><span class="w"> </span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">V</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">LinearMap.ker</span><span class="w"> </span><span class="n">φ</span><span class="o">)</span><span class="w"> </span><span class="bp">≃ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">range</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">φ.quotKerEquivRange</span> </pre></div> </div> <p>As an exercise, let us prove the correspondence theorem for subspaces of quotient spaces. Mathlib knows a slightly more precise version as <code class="docutils literal notranslate"><span class="pre">Submodule.comapMkQRelIso</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">Submodule</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">Submodule</span> <span class="k">#check</span> <span class="n">Submodule.map_comap_eq</span> <span class="k">#check</span> <span class="n">Submodule.comap_map_eq</span> <span class="k">#check</span><span class="w"> </span><span class="n">Submodule.map_comap_eq</span> <span class="k">#check</span><span class="w"> </span><span class="n">Submodule.comap_map_eq</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="o">(</span><span class="n">V</span> <span class="bp">⧸</span> <span class="n">E</span><span class="o">)</span> <span class="bp">≃</span> <span class="o">{</span> <span class="n">F</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span> <span class="bp">//</span> <span class="n">E</span> <span class="bp">≤</span> <span class="n">F</span> <span class="o">}</span> <span class="n">where</span> <span class="n">toFun</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">invFun</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">left_inv</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">right_inv</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="o">(</span><span class="n">V</span><span class="w"> </span><span class="bp">⧸</span><span class="w"> </span><span class="n">E</span><span class="o">)</span><span class="w"> </span><span class="bp">≃</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">//</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="o">}</span><span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">toFun</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">invFun</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">left_inv</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">right_inv</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> </section>
-
@@ -654,44 +655,44 @@ They are interesting because they form a <code class="docutils literal notranslate"><span class="pre">K</span></code>-algebra. In particular we can evaluate polynomialswith coefficients in <code class="docutils literal notranslate"><span class="pre">K</span></code> on them, and they can have eigenvalues and eigenvectors.</p> <p>Mathlib uses the abbreviation <code class="docutils literal notranslate"><span class="pre">Module.End</span> <span class="pre">K</span> <span class="pre">V</span> <span class="pre">:=</span> <span class="pre">V</span> <span class="pre">→ₗ[K]</span> <span class="pre">V</span></code> which is convenient when using a lot of these (especially after opening the <code class="docutils literal notranslate"><span class="pre">Module</span></code> namespace).</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">K</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Field</span> <span class="n">K</span><span class="o">]</span> <span class="o">{</span><span class="n">V</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">AddCommGroup</span> <span class="n">V</span><span class="o">]</span> <span class="o">[</span><span class="n">Module</span> <span class="n">K</span> <span class="n">V</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">K</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Field</span><span class="w"> </span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">V</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">AddCommGroup</span><span class="w"> </span><span class="n">V</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Module</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">]</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">W</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">AddCommGroup</span> <span class="n">W</span><span class="o">]</span> <span class="o">[</span><span class="n">Module</span> <span class="n">K</span> <span class="n">W</span><span class="o">]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">W</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">AddCommGroup</span><span class="w"> </span><span class="n">W</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Module</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">W</span><span class="o">]</span> <span class="kn">open</span> <span class="n">Polynomial</span> <span class="n">Module</span> <span class="n">LinearMap</span> <span class="kn">open</span><span class="w"> </span><span class="n">Polynomial</span><span class="w"> </span><span class="n">Module</span><span class="w"> </span><span class="n">LinearMap</span> <span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="n">ψ</span> <span class="o">:</span> <span class="n">End</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="n">φ</span> <span class="bp">*</span> <span class="n">ψ</span> <span class="bp">=</span> <span class="n">φ</span> <span class="bp">∘ₗ</span> <span class="n">ψ</span> <span class="o">:=</span> <span class="n">LinearMap.mul_eq_comp</span> <span class="n">φ</span> <span class="n">ψ</span> <span class="c1">-- `rfl` would also work</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="n">ψ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">End</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">ψ</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="bp">∘ₗ</span><span class="w"> </span><span class="n">ψ</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">LinearMap.mul_eq_comp</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">ψ</span><span class="w"> </span><span class="c1">-- `rfl` would also work</span> <span class="c1">-- evaluating `P` on `φ`</span> <span class="kd">example</span> <span class="o">(</span><span class="n">P</span> <span class="o">:</span> <span class="n">K</span><span class="o">[</span><span class="n">X</span><span class="o">])</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">End</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">V</span> <span class="o">:=</span> <span class="n">aeval</span> <span class="n">φ</span> <span class="n">P</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">P</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">K</span><span class="o">[</span><span class="n">X</span><span class="o">])</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">End</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">aeval</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">P</span> <span class="c1">-- evaluating `X` on `φ` gives back `φ`</span> <span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">End</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="n">aeval</span> <span class="n">φ</span> <span class="o">(</span><span class="n">X</span> <span class="o">:</span> <span class="n">K</span><span class="o">[</span><span class="n">X</span><span class="o">])</span> <span class="bp">=</span> <span class="n">φ</span> <span class="o">:=</span> <span class="n">aeval_X</span> <span class="n">φ</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">End</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">aeval</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="o">(</span><span class="n">X</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">K</span><span class="o">[</span><span class="n">X</span><span class="o">])</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">aeval_X</span><span class="w"> </span><span class="n">φ</span> </pre></div> </div> <p>As an exercise manipulating endomorphisms, subspaces and polynomials, let us prove the (binary) kernels lemma: for any endomorphism <span class="math notranslate nohighlight">\(φ\)</span> and any two relatively prime polynomials <span class="math notranslate nohighlight">\(P\)</span> and <span class="math notranslate nohighlight">\(Q\)</span>, we have <span class="math notranslate nohighlight">\(\ker P(φ) ⊕ \ker Q(φ) = \ker \big(PQ(φ)\big)\)</span>.</p> <p>Note that <code class="docutils literal notranslate"><span class="pre">IsCoprime</span> <span class="pre">x</span> <span class="pre">y</span></code> is defined as <code class="docutils literal notranslate"><span class="pre">∃</span> <span class="pre">a</span> <span class="pre">b,</span> <span class="pre">a</span> <span class="pre">*</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">b</span> <span class="pre">*</span> <span class="pre">y</span> <span class="pre">=</span> <span class="pre">1</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="n">Submodule.eq_bot_iff</span> <span class="k">#check</span> <span class="n">Submodule.mem_inf</span> <span class="k">#check</span> <span class="n">LinearMap.mem_ker</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="n">Submodule.eq_bot_iff</span> <span class="k">#check</span><span class="w"> </span><span class="n">Submodule.mem_inf</span> <span class="k">#check</span><span class="w"> </span><span class="n">LinearMap.mem_ker</span> <span class="kd">example</span> <span class="o">(</span><span class="n">P</span> <span class="n">Q</span> <span class="o">:</span> <span class="n">K</span><span class="o">[</span><span class="n">X</span><span class="o">])</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">IsCoprime</span> <span class="n">P</span> <span class="n">Q</span><span class="o">)</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">End</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="n">ker</span> <span class="o">(</span><span class="n">aeval</span> <span class="n">φ</span> <span class="n">P</span><span class="o">)</span> <span class="bp">⊓</span> <span class="n">ker</span> <span class="o">(</span><span class="n">aeval</span> <span class="n">φ</span> <span class="n">Q</span><span class="o">)</span> <span class="bp">=</span> <span class="bp">⊥</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">P</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">K</span><span class="o">[</span><span class="n">X</span><span class="o">])</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsCoprime</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">Q</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">End</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ker</span><span class="w"> </span><span class="o">(</span><span class="n">aeval</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">P</span><span class="o">)</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">ker</span><span class="w"> </span><span class="o">(</span><span class="n">aeval</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">Q</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">⊥</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="k">#check</span> <span class="n">Submodule.add_mem_sup</span> <span class="k">#check</span> <span class="n">map_mul</span> <span class="k">#check</span> <span class="n">LinearMap.mul_apply</span> <span class="k">#check</span> <span class="n">LinearMap.ker_le_ker_comp</span> <span class="k">#check</span><span class="w"> </span><span class="n">Submodule.add_mem_sup</span> <span class="k">#check</span><span class="w"> </span><span class="n">map_mul</span> <span class="k">#check</span><span class="w"> </span><span class="n">LinearMap.mul_apply</span> <span class="k">#check</span><span class="w"> </span><span class="n">LinearMap.ker_le_ker_comp</span> <span class="kd">example</span> <span class="o">(</span><span class="n">P</span> <span class="n">Q</span> <span class="o">:</span> <span class="n">K</span><span class="o">[</span><span class="n">X</span><span class="o">])</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">IsCoprime</span> <span class="n">P</span> <span class="n">Q</span><span class="o">)</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">End</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="n">ker</span> <span class="o">(</span><span class="n">aeval</span> <span class="n">φ</span> <span class="n">P</span><span class="o">)</span> <span class="bp">⊔</span> <span class="n">ker</span> <span class="o">(</span><span class="n">aeval</span> <span class="n">φ</span> <span class="n">Q</span><span class="o">)</span> <span class="bp">=</span> <span class="n">ker</span> <span class="o">(</span><span class="n">aeval</span> <span class="n">φ</span> <span class="o">(</span><span class="n">P</span><span class="bp">*</span><span class="n">Q</span><span class="o">))</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">P</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">K</span><span class="o">[</span><span class="n">X</span><span class="o">])</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsCoprime</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">Q</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">End</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">ker</span><span class="w"> </span><span class="o">(</span><span class="n">aeval</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">P</span><span class="o">)</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">ker</span><span class="w"> </span><span class="o">(</span><span class="n">aeval</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">Q</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">ker</span><span class="w"> </span><span class="o">(</span><span class="n">aeval</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="o">(</span><span class="n">P</span><span class="bp">*</span><span class="n">Q</span><span class="o">))</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>We now move to the discussions of eigenspaces and eigenvalues. The eigenspace
-
@@ -700,32 +701,32 @@ Eigenspaces are defined for all values of <code class="docutils literal notranslate"><span class="pre">a</span></code>, althoughthey are interesting only when they are non-zero. However an eigenvector is, by definition, a non-zero element of an eigenspace. The corresponding predicate is <code class="docutils literal notranslate"><span class="pre">End.HasEigenvector</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">End</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">K</span><span class="o">)</span> <span class="o">:</span> <span class="n">φ.eigenspace</span> <span class="n">a</span> <span class="bp">=</span> <span class="n">LinearMap.ker</span> <span class="o">(</span><span class="n">φ</span> <span class="bp">-</span> <span class="n">a</span> <span class="bp">•</span> <span class="mi">1</span><span class="o">)</span> <span class="o">:=</span> <span class="n">End.eigenspace_def</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">End</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">φ.eigenspace</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">LinearMap.ker</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">End.eigenspace_def</span> </pre></div> </div> <p>Then there is a predicate <code class="docutils literal notranslate"><span class="pre">End.HasEigenvalue</span></code> and the corresponding subtype <code class="docutils literal notranslate"><span class="pre">End.Eigenvalues</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">End</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">K</span><span class="o">)</span> <span class="o">:</span> <span class="n">φ.HasEigenvalue</span> <span class="n">a</span> <span class="bp">↔</span> <span class="n">φ.eigenspace</span> <span class="n">a</span> <span class="bp">≠</span> <span class="bp">⊥</span> <span class="o">:=</span> <span class="n">Iff.rfl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">End</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">φ.HasEigenvalue</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">φ.eigenspace</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≠</span><span class="w"> </span><span class="bp">⊥</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Iff.rfl</span> <span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">End</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">K</span><span class="o">)</span> <span class="o">:</span> <span class="n">φ.HasEigenvalue</span> <span class="n">a</span> <span class="bp">↔</span> <span class="bp">∃</span> <span class="n">v</span><span class="o">,</span> <span class="n">φ.HasEigenvector</span> <span class="n">a</span> <span class="n">v</span> <span class="o">:=</span> <span class="o">⟨</span><span class="n">End.HasEigenvalue.exists_hasEigenvector</span><span class="o">,</span> <span class="k">fun</span> <span class="o">⟨</span><span class="n">_</span><span class="o">,</span> <span class="n">hv</span><span class="o">⟩</span> <span class="bp">↦</span> <span class="n">φ.hasEigenvalue_of_hasEigenvector</span> <span class="n">hv</span><span class="o">⟩</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">End</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">φ.HasEigenvalue</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">v</span><span class="o">,</span><span class="w"> </span><span class="n">φ.HasEigenvector</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">⟨</span><span class="n">End.HasEigenvalue.exists_hasEigenvector</span><span class="o">,</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="o">⟨</span><span class="n">_</span><span class="o">,</span><span class="w"> </span><span class="n">hv</span><span class="o">⟩</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">φ.hasEigenvalue_of_hasEigenvector</span><span class="w"> </span><span class="n">hv</span><span class="o">⟩</span> <span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">End</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="n">φ.Eigenvalues</span> <span class="bp">=</span> <span class="o">{</span><span class="n">a</span> <span class="bp">//</span> <span class="n">φ.HasEigenvalue</span> <span class="n">a</span><span class="o">}</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">End</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">φ.Eigenvalues</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="bp">//</span><span class="w"> </span><span class="n">φ.HasEigenvalue</span><span class="w"> </span><span class="n">a</span><span class="o">}</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="c1">-- Eigenvalue are roots of the minimal polynomial</span> <span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">End</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">K</span><span class="o">)</span> <span class="o">:</span> <span class="n">φ.HasEigenvalue</span> <span class="n">a</span> <span class="bp">→</span> <span class="o">(</span><span class="n">minpoly</span> <span class="n">K</span> <span class="n">φ</span><span class="o">)</span><span class="bp">.</span><span class="n">IsRoot</span> <span class="n">a</span> <span class="o">:=</span> <span class="n">φ.isRoot_of_hasEigenvalue</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">End</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">φ.HasEigenvalue</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="o">(</span><span class="n">minpoly</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">φ</span><span class="o">)</span><span class="bp">.</span><span class="n">IsRoot</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">φ.isRoot_of_hasEigenvalue</span> <span class="c1">-- In finite dimension, the converse is also true (we will discuss dimension below)</span> <span class="kd">example</span> <span class="o">[</span><span class="n">FiniteDimensional</span> <span class="n">K</span> <span class="n">V</span><span class="o">]</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">End</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">K</span><span class="o">)</span> <span class="o">:</span> <span class="n">φ.HasEigenvalue</span> <span class="n">a</span> <span class="bp">↔</span> <span class="o">(</span><span class="n">minpoly</span> <span class="n">K</span> <span class="n">φ</span><span class="o">)</span><span class="bp">.</span><span class="n">IsRoot</span> <span class="n">a</span> <span class="o">:=</span> <span class="n">φ.hasEigenvalue_iff_isRoot</span> <span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">FiniteDimensional</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">End</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">φ.HasEigenvalue</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="o">(</span><span class="n">minpoly</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">φ</span><span class="o">)</span><span class="bp">.</span><span class="n">IsRoot</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">φ.hasEigenvalue_iff_isRoot</span> <span class="c1">-- Cayley-Hamilton</span> <span class="kd">example</span> <span class="o">[</span><span class="n">FiniteDimensional</span> <span class="n">K</span> <span class="n">V</span><span class="o">]</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">End</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="n">aeval</span> <span class="n">φ</span> <span class="n">φ.charpoly</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="n">φ.aeval_self_charpoly</span> <span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">FiniteDimensional</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">End</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">aeval</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">φ.charpoly</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">φ.aeval_self_charpoly</span> </pre></div> </div> </section>
-
@@ -741,16 +742,16 @@ For concrete matrices we can use the <code class="docutils literal notranslate"><span class="pre">!![…]</span></code> notation, lines are separated by semi-colonsand components of lines are separated by colons. When entries have a computable type such as <code class="docutils literal notranslate"><span class="pre">ℕ</span></code> or <code class="docutils literal notranslate"><span class="pre">ℚ</span></code>, we can use the <code class="docutils literal notranslate"><span class="pre">eval</span></code> command to play with basic operations.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span> <span class="n">matrices</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span><span class="w"> </span><span class="n">matrices</span> <span class="c1">-- Adding vectors</span> <span class="k">#eval</span> <span class="bp">!!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span> <span class="mi">2</span><span class="o">]</span> <span class="bp">+</span> <span class="bp">!!</span><span class="o">[</span><span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="o">]</span> <span class="c1">-- !![4, 6]</span> <span class="k">#eval</span><span class="w"> </span><span class="bp">!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="o">]</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="bp">!</span><span class="o">[</span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="o">]</span><span class="w"> </span><span class="c1">-- ![4, 6]</span> <span class="c1">-- Adding matrices</span> <span class="k">#eval</span> <span class="bp">!!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span> <span class="mi">2</span><span class="bp">;</span> <span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="o">]</span> <span class="bp">+</span> <span class="bp">!!</span><span class="o">[</span><span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="bp">;</span> <span class="mi">5</span><span class="o">,</span> <span class="mi">6</span><span class="o">]</span> <span class="c1">-- !![4, 6; 8, 10]</span> <span class="k">#eval</span><span class="w"> </span><span class="bp">!!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="bp">;</span><span class="w"> </span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="o">]</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="bp">!!</span><span class="o">[</span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="bp">;</span><span class="w"> </span><span class="mi">5</span><span class="o">,</span><span class="w"> </span><span class="mi">6</span><span class="o">]</span><span class="w"> </span><span class="c1">-- !![4, 6; 8, 10]</span> <span class="c1">-- Multiplying matrices</span> <span class="k">#eval</span> <span class="bp">!!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span> <span class="mi">2</span><span class="bp">;</span> <span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="o">]</span> <span class="bp">*</span> <span class="bp">!!</span><span class="o">[</span><span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="bp">;</span> <span class="mi">5</span><span class="o">,</span> <span class="mi">6</span><span class="o">]</span> <span class="c1">-- !![4, 6; 8, 10]</span> <span class="k">#eval</span><span class="w"> </span><span class="bp">!!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="bp">;</span><span class="w"> </span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="o">]</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="bp">!!</span><span class="o">[</span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="bp">;</span><span class="w"> </span><span class="mi">5</span><span class="o">,</span><span class="w"> </span><span class="mi">6</span><span class="o">]</span><span class="w"> </span><span class="c1">-- !![13, 16; 29, 36]</span> </pre></div> </div> <p>It is important to understand that this use of <code class="docutils literal notranslate"><span class="pre">#eval</span></code> is interesting only for
-
@@ -765,16 +766,16 @@ from the left (resp. right) interprets the vector as a row (resp. column) vector.This corresponds to operations <code class="docutils literal notranslate"><span class="pre">Matrix.vecMul</span></code>, with notation <code class="docutils literal notranslate"><span class="pre">ᵥ*</span></code> and <code class="docutils literal notranslate"><span class="pre">Matrix.mulVec</span></code>, with notation ` <cite>*ᵥ`</cite>. Those notations are scoped in the <code class="docutils literal notranslate"><span class="pre">Matrix</span></code> namespace that we therefore need to open.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">Matrix</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">Matrix</span> <span class="c1">-- matrices acting on vectors on the left</span> <span class="k">#eval</span> <span class="bp">!!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span> <span class="mi">2</span><span class="bp">;</span> <span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="o">]</span> <span class="bp">*ᵥ</span> <span class="bp">!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span> <span class="mi">1</span><span class="o">]</span> <span class="c1">-- ![3, 7]</span> <span class="k">#eval</span><span class="w"> </span><span class="bp">!!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="bp">;</span><span class="w"> </span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="o">]</span><span class="w"> </span><span class="bp">*ᵥ</span><span class="w"> </span><span class="bp">!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span><span class="o">]</span><span class="w"> </span><span class="c1">-- ![3, 7]</span> <span class="c1">-- matrices acting on vectors on the left, resulting in a size one matrix</span> <span class="k">#eval</span> <span class="bp">!!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span> <span class="mi">2</span><span class="o">]</span> <span class="bp">*ᵥ</span> <span class="bp">!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span> <span class="mi">1</span><span class="o">]</span> <span class="c1">-- ![3]</span> <span class="k">#eval</span><span class="w"> </span><span class="bp">!!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="o">]</span><span class="w"> </span><span class="bp">*ᵥ</span><span class="w"> </span><span class="bp">!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span><span class="o">]</span><span class="w"> </span><span class="c1">-- ![3]</span> <span class="c1">-- matrices acting on vectors on the right</span> <span class="k">#eval</span> <span class="bp">!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span> <span class="mi">1</span><span class="o">,</span> <span class="mi">1</span><span class="o">]</span> <span class="bp">ᵥ*</span> <span class="bp">!!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span> <span class="mi">2</span><span class="bp">;</span> <span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="bp">;</span> <span class="mi">5</span><span class="o">,</span> <span class="mi">6</span><span class="o">]</span> <span class="c1">-- ![9, 12]</span> <span class="k">#eval</span><span class="w"> </span><span class="bp">!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span><span class="o">]</span><span class="w"> </span><span class="bp">ᵥ*</span><span class="w"> </span><span class="bp">!!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="bp">;</span><span class="w"> </span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="bp">;</span><span class="w"> </span><span class="mi">5</span><span class="o">,</span><span class="w"> </span><span class="mi">6</span><span class="o">]</span><span class="w"> </span><span class="c1">-- ![9, 12]</span> </pre></div> </div> <p>In order to generate matrices with identical rows or columns specified by a vector, we
-
@@ -782,24 +783,24 @@ use <code class="docutils literal notranslate"><span class="pre">Matrix.row</span></code> and <code class="docutils literal notranslate"><span class="pre">Matrix.column</span></code>, with arguments the type indexing therows or columns and the vector. For instance one can get single row or single column matrixes (more precisely matrices whose rows or columns are indexed by <code class="docutils literal notranslate"><span class="pre">Fin</span> <span class="pre">1</span></code>).</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#eval</span> <span class="n">row</span> <span class="o">(</span><span class="n">Fin</span> <span class="mi">1</span><span class="o">)</span> <span class="bp">!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span> <span class="mi">2</span><span class="o">]</span> <span class="c1">-- !![1, 2]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#eval</span><span class="w"> </span><span class="n">row</span><span class="w"> </span><span class="o">(</span><span class="n">Fin</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="bp">!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="o">]</span><span class="w"> </span><span class="c1">-- !![1, 2]</span> <span class="k">#eval</span> <span class="n">col</span> <span class="o">(</span><span class="n">Fin</span> <span class="mi">1</span><span class="o">)</span> <span class="bp">!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span> <span class="mi">2</span><span class="o">]</span> <span class="c1">-- !![1; 2]</span> <span class="k">#eval</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">(</span><span class="n">Fin</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="bp">!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="o">]</span><span class="w"> </span><span class="c1">-- !![1; 2]</span> </pre></div> </div> <p>Other familiar operations include the vector dot product, matrix transpose, and, for square matrices, determinant and trace.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="c1">-- vector dot product</span> <span class="k">#eval</span> <span class="bp">!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span> <span class="mi">2</span><span class="o">]</span> <span class="bp">⬝ᵥ</span> <span class="bp">!</span><span class="o">[</span><span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="o">]</span> <span class="c1">-- `11`</span> <span class="k">#eval</span><span class="w"> </span><span class="bp">!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="o">]</span><span class="w"> </span><span class="bp">⬝ᵥ</span><span class="w"> </span><span class="bp">!</span><span class="o">[</span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="o">]</span><span class="w"> </span><span class="c1">-- `11`</span> <span class="c1">-- matrix transpose</span> <span class="k">#eval</span> <span class="bp">!!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span> <span class="mi">2</span><span class="bp">;</span> <span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="o">]</span><span class="bp">ᵀ</span> <span class="c1">-- `!![1, 3; 2, 4]`</span> <span class="k">#eval</span><span class="w"> </span><span class="bp">!!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="bp">;</span><span class="w"> </span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="o">]</span><span class="bp">ᵀ</span><span class="w"> </span><span class="c1">-- `!![1, 3; 2, 4]`</span> <span class="c1">-- determinant</span> <span class="k">#eval</span> <span class="bp">!!</span><span class="o">[(</span><span class="mi">1</span> <span class="o">:</span> <span class="n">ℤ</span><span class="o">),</span> <span class="mi">2</span><span class="bp">;</span> <span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="o">]</span><span class="bp">.</span><span class="n">det</span> <span class="c1">-- `-2`</span> <span class="k">#eval</span><span class="w"> </span><span class="bp">!!</span><span class="o">[(</span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℤ</span><span class="o">),</span><span class="w"> </span><span class="mi">2</span><span class="bp">;</span><span class="w"> </span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="o">]</span><span class="bp">.</span><span class="n">det</span><span class="w"> </span><span class="c1">-- `-2`</span> <span class="c1">-- trace</span> <span class="k">#eval</span> <span class="bp">!!</span><span class="o">[(</span><span class="mi">1</span> <span class="o">:</span> <span class="n">ℤ</span><span class="o">),</span> <span class="mi">2</span><span class="bp">;</span> <span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="o">]</span><span class="bp">.</span><span class="n">trace</span> <span class="c1">-- `5`</span> <span class="k">#eval</span><span class="w"> </span><span class="bp">!!</span><span class="o">[(</span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℤ</span><span class="o">),</span><span class="w"> </span><span class="mi">2</span><span class="bp">;</span><span class="w"> </span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="o">]</span><span class="bp">.</span><span class="n">trace</span><span class="w"> </span><span class="c1">-- `5`</span> </pre></div> </div> <p>When entries do not have a computable type, for instance if they are real numbers, we cannot
-
@@ -808,14 +809,14 @@ considerably expanding the trusted code base (i.e. the part of Lean that you need to trust whenchecking proofs).</p> <p>So it is good to also use the <code class="docutils literal notranslate"><span class="pre">simp</span></code> and <code class="docutils literal notranslate"><span class="pre">norm_num</span></code> tactics in proofs, or their command counter-part for quick exploration.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="bp">#</span><span class="n">simp</span> <span class="bp">!!</span><span class="o">[(</span><span class="mi">1</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">),</span> <span class="mi">2</span><span class="bp">;</span> <span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="o">]</span><span class="bp">.</span><span class="n">det</span> <span class="c1">-- `4 - 2*3`</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="bp">#</span><span class="n">simp</span><span class="w"> </span><span class="bp">!!</span><span class="o">[(</span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">),</span><span class="w"> </span><span class="mi">2</span><span class="bp">;</span><span class="w"> </span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="o">]</span><span class="bp">.</span><span class="n">det</span><span class="w"> </span><span class="c1">-- `4 - 2*3`</span> <span class="bp">#</span><span class="n">norm_num</span> <span class="bp">!!</span><span class="o">[(</span><span class="mi">1</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">),</span> <span class="mi">2</span><span class="bp">;</span> <span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="o">]</span><span class="bp">.</span><span class="n">det</span> <span class="c1">-- `-2`</span> <span class="bp">#</span><span class="n">norm_num</span><span class="w"> </span><span class="bp">!!</span><span class="o">[(</span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">),</span><span class="w"> </span><span class="mi">2</span><span class="bp">;</span><span class="w"> </span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="o">]</span><span class="bp">.</span><span class="n">det</span><span class="w"> </span><span class="c1">-- `-2`</span> <span class="bp">#</span><span class="n">norm_num</span> <span class="bp">!!</span><span class="o">[(</span><span class="mi">1</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">),</span> <span class="mi">2</span><span class="bp">;</span> <span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="o">]</span><span class="bp">.</span><span class="n">trace</span> <span class="c1">-- `5`</span> <span class="bp">#</span><span class="n">norm_num</span><span class="w"> </span><span class="bp">!!</span><span class="o">[(</span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">),</span><span class="w"> </span><span class="mi">2</span><span class="bp">;</span><span class="w"> </span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="o">]</span><span class="bp">.</span><span class="n">trace</span><span class="w"> </span><span class="c1">-- `5`</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="n">d</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="k">in</span> <span class="bp">#</span><span class="n">simp</span> <span class="bp">!!</span><span class="o">[</span><span class="n">a</span><span class="o">,</span> <span class="n">b</span><span class="bp">;</span> <span class="n">c</span><span class="o">,</span> <span class="n">d</span><span class="o">]</span><span class="bp">.</span><span class="n">det</span> <span class="c1">-- `a * d – b * c`</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="k">in</span> <span class="bp">#</span><span class="n">simp</span><span class="w"> </span><span class="bp">!!</span><span class="o">[</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">b</span><span class="bp">;</span><span class="w"> </span><span class="n">c</span><span class="o">,</span><span class="w"> </span><span class="n">d</span><span class="o">]</span><span class="bp">.</span><span class="n">det</span><span class="w"> </span><span class="c1">-- `a * d – b * c`</span> </pre></div> </div> <p>The next important operation on square matrices is inversion.
-
@@ -826,7 +827,7 @@ <p>More precisely, there is general function <code class="docutils literal notranslate"><span class="pre">Ring.inverse</span></code> that does this in any ring,and, for any matrix <code class="docutils literal notranslate"><span class="pre">A</span></code>, <code class="docutils literal notranslate"><span class="pre">A⁻¹</span></code> is defined as <code class="docutils literal notranslate"><span class="pre">Ring.inverse</span> <span class="pre">A.det</span> <span class="pre">•</span> <span class="pre">A.adjugate</span></code>. According to Cramer’s rule, this is indeed the inverse of <code class="docutils literal notranslate"><span class="pre">A</span></code> when the determinant of <code class="docutils literal notranslate"><span class="pre">A</span></code> is not zero.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="bp">#</span><span class="n">norm_num</span> <span class="o">[</span><span class="n">Matrix.inv_def</span><span class="o">]</span> <span class="bp">!!</span><span class="o">[(</span><span class="mi">1</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">),</span> <span class="mi">2</span><span class="bp">;</span> <span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="o">]</span><span class="bp">⁻¹</span> <span class="c1">-- !![-2, 1; 3 / 2, -(1 / 2)]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="bp">#</span><span class="n">norm_num</span><span class="w"> </span><span class="o">[</span><span class="n">Matrix.inv_def</span><span class="o">]</span><span class="w"> </span><span class="bp">!!</span><span class="o">[(</span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">),</span><span class="w"> </span><span class="mi">2</span><span class="bp">;</span><span class="w"> </span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="o">]</span><span class="bp">⁻¹</span><span class="w"> </span><span class="c1">-- !![-2, 1; 3 / 2, -(1 / 2)]</span> </pre></div> </div> <p>Of course this definition is really useful only for invertible matrices.
-
@@ -835,18 +836,18 @@ For instance, the <code class="docutils literal notranslate"><span class="pre">simp</span></code> call in the next example will use the <code class="docutils literal notranslate"><span class="pre">inv_mul_of_invertible</span></code>lemma which has an <code class="docutils literal notranslate"><span class="pre">Invertible</span></code> type-class assumption, so it will trigger only if this can be found by the type-class synthesis system. Here we make this fact available using a <code class="docutils literal notranslate"><span class="pre">have</span></code> statement.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="bp">!!</span><span class="o">[(</span><span class="mi">1</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">),</span> <span class="mi">2</span><span class="bp">;</span> <span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="o">]</span><span class="bp">⁻¹</span> <span class="bp">*</span> <span class="bp">!!</span><span class="o">[(</span><span class="mi">1</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">),</span> <span class="mi">2</span><span class="bp">;</span> <span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="o">]</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="k">have</span> <span class="o">:</span> <span class="n">Invertible</span> <span class="bp">!!</span><span class="o">[(</span><span class="mi">1</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">),</span> <span class="mi">2</span><span class="bp">;</span> <span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="o">]</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">Matrix.invertibleOfIsUnitDet</span> <span class="n">norm_num</span> <span class="n">simp</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">!!</span><span class="o">[(</span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">),</span><span class="w"> </span><span class="mi">2</span><span class="bp">;</span><span class="w"> </span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="o">]</span><span class="bp">⁻¹</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="bp">!!</span><span class="o">[(</span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">),</span><span class="w"> </span><span class="mi">2</span><span class="bp">;</span><span class="w"> </span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="o">]</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Invertible</span><span class="w"> </span><span class="bp">!!</span><span class="o">[(</span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">),</span><span class="w"> </span><span class="mi">2</span><span class="bp">;</span><span class="w"> </span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="o">]</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">Matrix.invertibleOfIsUnitDet</span> <span class="w"> </span><span class="n">norm_num</span> <span class="w"> </span><span class="n">simp</span> </pre></div> </div> <p>In this fully concrete case, we could also use the <code class="docutils literal notranslate"><span class="pre">norm_num</span></code> machinery, and <code class="docutils literal notranslate"><span class="pre">apply?</span></code> to find the final line:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="bp">!!</span><span class="o">[(</span><span class="mi">1</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">),</span> <span class="mi">2</span><span class="bp">;</span> <span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="o">]</span><span class="bp">⁻¹</span> <span class="bp">*</span> <span class="bp">!!</span><span class="o">[(</span><span class="mi">1</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">),</span> <span class="mi">2</span><span class="bp">;</span> <span class="mi">3</span><span class="o">,</span> <span class="mi">4</span><span class="o">]</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">norm_num</span> <span class="o">[</span><span class="n">Matrix.inv_def</span><span class="o">]</span> <span class="n">exact</span> <span class="n">one_fin_two.symm</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">!!</span><span class="o">[(</span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">),</span><span class="w"> </span><span class="mi">2</span><span class="bp">;</span><span class="w"> </span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="o">]</span><span class="bp">⁻¹</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="bp">!!</span><span class="o">[(</span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">),</span><span class="w"> </span><span class="mi">2</span><span class="bp">;</span><span class="w"> </span><span class="mi">3</span><span class="o">,</span><span class="w"> </span><span class="mi">4</span><span class="o">]</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">norm_num</span><span class="w"> </span><span class="o">[</span><span class="n">Matrix.inv_def</span><span class="o">]</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">one_fin_two.symm</span> </pre></div> </div> <p>All the concrete matrices above have their rows and columns indexed by <code class="docutils literal notranslate"><span class="pre">Fin</span> <span class="pre">n</span></code> for
-
@@ -870,27 +871,27 @@ <p>But then the next two examples reveal that Lean uses the point-wise multiplicationon <code class="docutils literal notranslate"><span class="pre">Fin</span> <span class="pre">2</span> <span class="pre">→</span> <span class="pre">Fin</span> <span class="pre">2</span> <span class="pre">→</span> <span class="pre">ℤ</span></code> but the matrix multiplication on <code class="docutils literal notranslate"><span class="pre">Matrix</span> <span class="pre">(Fin</span> <span class="pre">2)</span> <span class="pre">(Fin</span> <span class="pre">2)</span> <span class="pre">ℤ</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="k">fun</span> <span class="n">_</span> <span class="bp">↦</span> <span class="mi">1</span> <span class="o">:</span> <span class="n">Fin</span> <span class="mi">2</span> <span class="bp">→</span> <span class="n">Fin</span> <span class="mi">2</span> <span class="bp">→</span> <span class="n">ℤ</span><span class="o">)</span> <span class="bp">=</span> <span class="bp">!!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span> <span class="mi">1</span><span class="bp">;</span> <span class="mi">1</span><span class="o">,</span> <span class="mi">1</span><span class="o">]</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ext</span> <span class="n">i</span> <span class="n">j</span> <span class="n">fin_cases</span> <span class="n">i</span> <span class="bp"><;></span> <span class="n">fin_cases</span> <span class="n">j</span> <span class="bp"><;></span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Fin</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Fin</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℤ</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">!!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span><span class="bp">;</span><span class="w"> </span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span><span class="o">]</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="n">j</span> <span class="w"> </span><span class="n">fin_cases</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">fin_cases</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">rfl</span> <span class="kd">example</span> <span class="o">:</span> <span class="o">(</span><span class="k">fun</span> <span class="n">_</span> <span class="bp">↦</span> <span class="mi">1</span> <span class="o">:</span> <span class="n">Fin</span> <span class="mi">2</span> <span class="bp">→</span> <span class="n">Fin</span> <span class="mi">2</span> <span class="bp">→</span> <span class="n">ℤ</span><span class="o">)</span> <span class="bp">*</span> <span class="o">(</span><span class="k">fun</span> <span class="n">_</span> <span class="bp">↦</span> <span class="mi">1</span> <span class="o">:</span> <span class="n">Fin</span> <span class="mi">2</span> <span class="bp">→</span> <span class="n">Fin</span> <span class="mi">2</span> <span class="bp">→</span> <span class="n">ℤ</span><span class="o">)</span> <span class="bp">=</span> <span class="bp">!!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span> <span class="mi">1</span><span class="bp">;</span> <span class="mi">1</span><span class="o">,</span> <span class="mi">1</span><span class="o">]</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">ext</span> <span class="n">i</span> <span class="n">j</span> <span class="n">fin_cases</span> <span class="n">i</span> <span class="bp"><;></span> <span class="n">fin_cases</span> <span class="n">j</span> <span class="bp"><;></span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Fin</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Fin</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℤ</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Fin</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Fin</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℤ</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">!!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span><span class="bp">;</span><span class="w"> </span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span><span class="o">]</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">ext</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="n">j</span> <span class="w"> </span><span class="n">fin_cases</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">fin_cases</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="bp"><;></span><span class="w"> </span><span class="n">rfl</span> <span class="kd">example</span> <span class="o">:</span> <span class="bp">!!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span> <span class="mi">1</span><span class="bp">;</span> <span class="mi">1</span><span class="o">,</span> <span class="mi">1</span><span class="o">]</span> <span class="bp">*</span> <span class="bp">!!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span> <span class="mi">1</span><span class="bp">;</span> <span class="mi">1</span><span class="o">,</span> <span class="mi">1</span><span class="o">]</span> <span class="bp">=</span> <span class="bp">!!</span><span class="o">[</span><span class="mi">2</span><span class="o">,</span> <span class="mi">2</span><span class="bp">;</span> <span class="mi">2</span><span class="o">,</span> <span class="mi">2</span><span class="o">]</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">norm_num</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">!!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span><span class="bp">;</span><span class="w"> </span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span><span class="o">]</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="bp">!!</span><span class="o">[</span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span><span class="bp">;</span><span class="w"> </span><span class="mi">1</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span><span class="o">]</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">!!</span><span class="o">[</span><span class="mi">2</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="bp">;</span><span class="w"> </span><span class="mi">2</span><span class="o">,</span><span class="w"> </span><span class="mi">2</span><span class="o">]</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">norm_num</span> </pre></div> </div> <p>In order to define matrices as functions without losing the benefits of <code class="docutils literal notranslate"><span class="pre">Matrix</span></code> for type class synthesis, we can use the equivalence <code class="docutils literal notranslate"><span class="pre">Matrix.of</span></code> between functions and matrices. This equivalence is secretly defined using <code class="docutils literal notranslate"><span class="pre">Equiv.refl</span></code>.</p> <p>For instance we can define Vandermonde matrices corresponding to a vector <code class="docutils literal notranslate"><span class="pre">v</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">(</span><span class="n">v</span> <span class="o">:</span> <span class="n">Fin</span> <span class="n">n</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">Matrix.vandermonde</span> <span class="n">v</span> <span class="bp">=</span> <span class="n">Matrix.of</span> <span class="o">(</span><span class="k">fun</span> <span class="n">i</span> <span class="n">j</span> <span class="o">:</span> <span class="n">Fin</span> <span class="n">n</span> <span class="bp">↦</span> <span class="n">v</span> <span class="n">i</span> <span class="bp">^</span> <span class="o">(</span><span class="n">j</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">))</span> <span class="o">:=</span> <span class="n">rfl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">v</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Fin</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Matrix.vandermonde</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">Matrix.of</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Fin</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="o">(</span><span class="n">j</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">))</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">end</span> <span class="kd">end</span> <span class="n">matrices</span> <span class="kd">end</span><span class="w"> </span><span class="n">matrices</span> </pre></div> </div> </section>
-
@@ -916,23 +917,23 @@ Evaluating such a function coming from a basis <code class="docutils literal notranslate"><span class="pre">B</span></code> at a vector <code class="docutils literal notranslate"><span class="pre">v</span></code> and<code class="docutils literal notranslate"><span class="pre">i</span> <span class="pre">:</span> <span class="pre">ι</span></code> returns the component (or coordinate) of <code class="docutils literal notranslate"><span class="pre">v</span></code> on the <code class="docutils literal notranslate"><span class="pre">i</span></code>-th basis vector.</p> <p>The type of bases indexed by a type <code class="docutils literal notranslate"><span class="pre">ι</span></code> of <code class="docutils literal notranslate"><span class="pre">V</span></code> as a <code class="docutils literal notranslate"><span class="pre">K</span></code> vector space is <code class="docutils literal notranslate"><span class="pre">Basis</span> <span class="pre">ι</span> <span class="pre">K</span> <span class="pre">V</span></code>. The isomorphism is called <code class="docutils literal notranslate"><span class="pre">Basis.repr</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">K</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Field</span> <span class="n">K</span><span class="o">]</span> <span class="o">{</span><span class="n">V</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">AddCommGroup</span> <span class="n">V</span><span class="o">]</span> <span class="o">[</span><span class="n">Module</span> <span class="n">K</span> <span class="n">V</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">K</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Field</span><span class="w"> </span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">V</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">AddCommGroup</span><span class="w"> </span><span class="n">V</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Module</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">]</span> <span class="kn">section</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">ι</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">(</span><span class="n">B</span> <span class="o">:</span> <span class="n">Basis</span> <span class="n">ι</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">(</span><span class="n">v</span> <span class="o">:</span> <span class="n">V</span><span class="o">)</span> <span class="o">(</span><span class="n">i</span> <span class="o">:</span> <span class="n">ι</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">ι</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">B</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Basis</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">v</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">i</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="o">)</span> <span class="c1">-- The basis vector with index ``i``</span> <span class="k">#check</span> <span class="o">(</span><span class="n">B</span> <span class="n">i</span> <span class="o">:</span> <span class="n">V</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">B</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="o">)</span> <span class="c1">-- the linear isomorphism with the model space given by ``B``</span> <span class="k">#check</span> <span class="o">(</span><span class="n">B.repr</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">≃ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">ι</span> <span class="bp">→₀</span> <span class="n">K</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">B.repr</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">≃ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→₀</span><span class="w"> </span><span class="n">K</span><span class="o">)</span> <span class="c1">-- the component function of ``v``</span> <span class="k">#check</span> <span class="o">(</span><span class="n">B.repr</span> <span class="n">v</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→₀</span> <span class="n">K</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">B.repr</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→₀</span><span class="w"> </span><span class="n">K</span><span class="o">)</span> <span class="c1">-- the component of ``v`` with index ``i``</span> <span class="k">#check</span> <span class="o">(</span><span class="n">B.repr</span> <span class="n">v</span> <span class="n">i</span> <span class="o">:</span> <span class="n">K</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">B.repr</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">K</span><span class="o">)</span> </pre></div> </div> <p>Instead of starting with such an isomorphism, one can start with a family <code class="docutils literal notranslate"><span class="pre">b</span></code> of vectors that is
-
@@ -942,15 +943,15 @@ Here <code class="docutils literal notranslate"><span class="pre">⊤</span></code> is the top submodule of <code class="docutils literal notranslate"><span class="pre">V</span></code>, i.e. <code class="docutils literal notranslate"><span class="pre">V</span></code> seen as submodule of itself.This spelling looks a bit tortuous, but we will see below that it is almost equivalent by definition to the more readable <code class="docutils literal notranslate"><span class="pre">∀</span> <span class="pre">v,</span> <span class="pre">v</span> <span class="pre">∈</span> <span class="pre">Submodule.span</span> <span class="pre">K</span> <span class="pre">(Set.range</span> <span class="pre">b)</span></code> (the underscores in the snippet below refers to the useless information <code class="docutils literal notranslate"><span class="pre">v</span> <span class="pre">∈</span> <span class="pre">⊤</span></code>).</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">noncomputable</span> <span class="kd">example</span> <span class="o">(</span><span class="n">b</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">V</span><span class="o">)</span> <span class="o">(</span><span class="n">b_indep</span> <span class="o">:</span> <span class="n">LinearIndependent</span> <span class="n">K</span> <span class="n">b</span><span class="o">)</span> <span class="o">(</span><span class="n">b_spans</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">v</span><span class="o">,</span> <span class="n">v</span> <span class="bp">∈</span> <span class="n">Submodule.span</span> <span class="n">K</span> <span class="o">(</span><span class="n">Set.range</span> <span class="n">b</span><span class="o">))</span> <span class="o">:</span> <span class="n">Basis</span> <span class="n">ι</span> <span class="n">K</span> <span class="n">V</span> <span class="o">:=</span> <span class="n">Basis.mk</span> <span class="n">b_indep</span> <span class="o">(</span><span class="k">fun</span> <span class="n">v</span> <span class="n">_</span> <span class="bp">↦</span> <span class="n">b_spans</span> <span class="n">v</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">noncomputable</span><span class="w"> </span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">b_indep</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">LinearIndependent</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="n">b_spans</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">v</span><span class="o">,</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">Submodule.span</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="o">(</span><span class="n">Set.range</span><span class="w"> </span><span class="n">b</span><span class="o">))</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Basis</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Basis.mk</span><span class="w"> </span><span class="n">b_indep</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">b_spans</span><span class="w"> </span><span class="n">v</span><span class="o">)</span> <span class="c1">-- The family of vectors underlying the above basis is indeed ``b``.</span> <span class="kd">example</span> <span class="o">(</span><span class="n">b</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">V</span><span class="o">)</span> <span class="o">(</span><span class="n">b_indep</span> <span class="o">:</span> <span class="n">LinearIndependent</span> <span class="n">K</span> <span class="n">b</span><span class="o">)</span> <span class="o">(</span><span class="n">b_spans</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">v</span><span class="o">,</span> <span class="n">v</span> <span class="bp">∈</span> <span class="n">Submodule.span</span> <span class="n">K</span> <span class="o">(</span><span class="n">Set.range</span> <span class="n">b</span><span class="o">))</span> <span class="o">(</span><span class="n">i</span> <span class="o">:</span> <span class="n">ι</span><span class="o">)</span> <span class="o">:</span> <span class="n">Basis.mk</span> <span class="n">b_indep</span> <span class="o">(</span><span class="k">fun</span> <span class="n">v</span> <span class="n">_</span> <span class="bp">↦</span> <span class="n">b_spans</span> <span class="n">v</span><span class="o">)</span> <span class="n">i</span> <span class="bp">=</span> <span class="n">b</span> <span class="n">i</span> <span class="o">:=</span> <span class="n">Basis.mk_apply</span> <span class="n">b_indep</span> <span class="o">(</span><span class="k">fun</span> <span class="n">v</span> <span class="n">_</span> <span class="bp">↦</span> <span class="n">b_spans</span> <span class="n">v</span><span class="o">)</span> <span class="n">i</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">b_indep</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">LinearIndependent</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="n">b_spans</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">v</span><span class="o">,</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">Submodule.span</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="o">(</span><span class="n">Set.range</span><span class="w"> </span><span class="n">b</span><span class="o">))</span><span class="w"> </span><span class="o">(</span><span class="n">i</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Basis.mk</span><span class="w"> </span><span class="n">b_indep</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">b_spans</span><span class="w"> </span><span class="n">v</span><span class="o">)</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Basis.mk_apply</span><span class="w"> </span><span class="n">b_indep</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">b_spans</span><span class="w"> </span><span class="n">v</span><span class="o">)</span><span class="w"> </span><span class="n">i</span> </pre></div> </div> <p>In particular the model vector space <code class="docutils literal notranslate"><span class="pre">ι</span> <span class="pre">→₀</span> <span class="pre">K</span></code> has a so-called canonical basis whose <code class="docutils literal notranslate"><span class="pre">repr</span></code>
-
@@ -960,27 +961,27 @@ <code class="docutils literal notranslate"><span class="pre">basisSingleOne</span></code> refers to the fact that basis vectors are functions whichvanish expect for a single input value. More precisely the basis vector indexed by <code class="docutils literal notranslate"><span class="pre">i</span> <span class="pre">:</span> <span class="pre">ι</span></code> is <code class="docutils literal notranslate"><span class="pre">Finsupp.single</span> <span class="pre">i</span> <span class="pre">1</span></code> which is the finitely supported function taking value <code class="docutils literal notranslate"><span class="pre">1</span></code> at <code class="docutils literal notranslate"><span class="pre">i</span></code> and <code class="docutils literal notranslate"><span class="pre">0</span></code> everywhere else.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">[</span><span class="n">DecidableEq</span> <span class="n">ι</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">[</span><span class="n">DecidableEq</span><span class="w"> </span><span class="n">ι</span><span class="o">]</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">Finsupp.basisSingleOne.repr</span> <span class="bp">=</span> <span class="n">LinearEquiv.refl</span> <span class="n">K</span> <span class="o">(</span><span class="n">ι</span> <span class="bp">→₀</span> <span class="n">K</span><span class="o">)</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Finsupp.basisSingleOne.repr</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">LinearEquiv.refl</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="o">(</span><span class="n">ι</span><span class="w"> </span><span class="bp">→₀</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">example</span> <span class="o">(</span><span class="n">i</span> <span class="o">:</span> <span class="n">ι</span><span class="o">)</span> <span class="o">:</span> <span class="n">Finsupp.basisSingleOne</span> <span class="n">i</span> <span class="bp">=</span> <span class="n">Finsupp.single</span> <span class="n">i</span> <span class="mi">1</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">i</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Finsupp.basisSingleOne</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">Finsupp.single</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> </pre></div> </div> <p>The story of finitely supported functions is unneeded when the indexing type is finite. In this case we can use the simpler <code class="docutils literal notranslate"><span class="pre">Pi.basisFun</span></code> which gives a basis of the whole <code class="docutils literal notranslate"><span class="pre">ι</span> <span class="pre">→</span> <span class="pre">K</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">[</span><span class="n">Finite</span> <span class="n">ι</span><span class="o">]</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">K</span><span class="o">)</span> <span class="o">(</span><span class="n">i</span> <span class="o">:</span> <span class="n">ι</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="k">Pi</span><span class="bp">.</span><span class="n">basisFun</span> <span class="n">K</span> <span class="n">ι</span><span class="o">)</span><span class="bp">.</span><span class="n">repr</span> <span class="n">x</span> <span class="n">i</span> <span class="bp">=</span> <span class="n">x</span> <span class="n">i</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">Finite</span><span class="w"> </span><span class="n">ι</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">i</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="k">Pi</span><span class="bp">.</span><span class="n">basisFun</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">ι</span><span class="o">)</span><span class="bp">.</span><span class="n">repr</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">simp</span> </pre></div> </div> <p>Going back to the general case of bases of abstract vector spaces, we can express any vector as a linear combination of basis vectors. Let us first see the easy case of finite bases.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">[</span><span class="n">Fintype</span> <span class="n">ι</span><span class="o">]</span> <span class="o">:</span> <span class="bp">∑</span> <span class="n">i</span> <span class="o">:</span> <span class="n">ι</span><span class="o">,</span> <span class="n">B.repr</span> <span class="n">v</span> <span class="n">i</span> <span class="bp">•</span> <span class="o">(</span><span class="n">B</span> <span class="n">i</span><span class="o">)</span> <span class="bp">=</span> <span class="n">v</span> <span class="o">:=</span> <span class="n">B.sum_repr</span> <span class="n">v</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">Fintype</span><span class="w"> </span><span class="n">ι</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∑</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="o">,</span><span class="w"> </span><span class="n">B.repr</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="o">(</span><span class="n">B</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">B.sum_repr</span><span class="w"> </span><span class="n">v</span> </pre></div> </div> <p>When <code class="docutils literal notranslate"><span class="pre">ι</span></code> is not finite, the above statement makes no sense a priori: we cannot take a sum over <code class="docutils literal notranslate"><span class="pre">ι</span></code>.
-
@@ -993,24 +994,24 @@ function <code class="docutils literal notranslate"><span class="pre">f</span></code> from <code class="docutils literal notranslate"><span class="pre">ι</span></code> to <code class="docutils literal notranslate"><span class="pre">V</span></code>, <code class="docutils literal notranslate"><span class="pre">Finsupp.linearCombination</span> <span class="pre">K</span> <span class="pre">f</span> <span class="pre">c</span></code> is thesum over the support of <code class="docutils literal notranslate"><span class="pre">c</span></code> of the scalar multiplication <code class="docutils literal notranslate"><span class="pre">c</span> <span class="pre">•</span> <span class="pre">f</span></code>. In particular, we can replace it by a sum over any finite set containing the support of <code class="docutils literal notranslate"><span class="pre">c</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">c</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→₀</span> <span class="n">K</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">V</span><span class="o">)</span> <span class="o">(</span><span class="n">s</span> <span class="o">:</span> <span class="n">Finset</span> <span class="n">ι</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">c.support</span> <span class="bp">⊆</span> <span class="n">s</span><span class="o">)</span> <span class="o">:</span> <span class="n">Finsupp.linearCombination</span> <span class="n">K</span> <span class="n">f</span> <span class="n">c</span> <span class="bp">=</span> <span class="bp">∑</span> <span class="n">i</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="n">c</span> <span class="n">i</span> <span class="bp">•</span> <span class="n">f</span> <span class="n">i</span> <span class="o">:=</span> <span class="n">Finsupp.linearCombination_apply_of_mem_supported</span> <span class="n">K</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→₀</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Finset</span><span class="w"> </span><span class="n">ι</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">c.support</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Finsupp.linearCombination</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">∑</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Finsupp.linearCombination_apply_of_mem_supported</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>One could also assume that <code class="docutils literal notranslate"><span class="pre">f</span></code> is finitely supported and still get a well defined sum. But the choice made by <code class="docutils literal notranslate"><span class="pre">Finsupp.linearCombination</span></code> is the one relevant to our basis discussion since it allows to state the generalization of <code class="docutils literal notranslate"><span class="pre">Basis.sum_repr</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">Finsupp.linearCombination</span> <span class="n">K</span> <span class="n">B</span> <span class="o">(</span><span class="n">B.repr</span> <span class="n">v</span><span class="o">)</span> <span class="bp">=</span> <span class="n">v</span> <span class="o">:=</span> <span class="n">B.linearCombination_repr</span> <span class="n">v</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Finsupp.linearCombination</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="o">(</span><span class="n">B.repr</span><span class="w"> </span><span class="n">v</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">B.linearCombination_repr</span><span class="w"> </span><span class="n">v</span> </pre></div> </div> <p>One could wonder why <code class="docutils literal notranslate"><span class="pre">K</span></code> is an explicit argument here, despite the fact it can be inferred from the type of <code class="docutils literal notranslate"><span class="pre">c</span></code>. The point is that the partially applied <code class="docutils literal notranslate"><span class="pre">Finsupp.linearCombination</span> <span class="pre">K</span> <span class="pre">f</span></code> is interesting in itself. It is not a bare function from <code class="docutils literal notranslate"><span class="pre">ι</span> <span class="pre">→₀</span> <span class="pre">K</span></code> to <code class="docutils literal notranslate"><span class="pre">V</span></code> but a <code class="docutils literal notranslate"><span class="pre">K</span></code>-linear map.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">V</span><span class="o">)</span> <span class="k">in</span> <span class="k">#check</span> <span class="o">(</span><span class="n">Finsupp.linearCombination</span> <span class="n">K</span> <span class="n">f</span> <span class="o">:</span> <span class="o">(</span><span class="n">ι</span> <span class="bp">→₀</span> <span class="n">K</span><span class="o">)</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">V</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="k">in</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">Finsupp.linearCombination</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">ι</span><span class="w"> </span><span class="bp">→₀</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">V</span><span class="o">)</span> </pre></div> </div> <p>The above subtlety also explains why dot notation cannot be used to write
-
@@ -1030,41 +1031,41 @@ This isomorphism is characterized by the fact that it sends any function <code class="docutils literal notranslate"><span class="pre">u</span> <span class="pre">:</span> <span class="pre">ι</span> <span class="pre">→</span> <span class="pre">W</span></code>to a linear map sending the basis vector <code class="docutils literal notranslate"><span class="pre">B</span> <span class="pre">i</span></code> to <code class="docutils literal notranslate"><span class="pre">u</span> <span class="pre">i</span></code>, for every <code class="docutils literal notranslate"><span class="pre">i</span> <span class="pre">:</span> <span class="pre">ι</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">W</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">AddCommGroup</span> <span class="n">W</span><span class="o">]</span> <span class="o">[</span><span class="n">Module</span> <span class="n">K</span> <span class="n">W</span><span class="o">]</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span><span class="o">)</span> <span class="o">(</span><span class="n">u</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">W</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">W</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">AddCommGroup</span><span class="w"> </span><span class="n">W</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Module</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">W</span><span class="o">]</span> <span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">W</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">B.constr</span> <span class="n">K</span> <span class="o">:</span> <span class="o">(</span><span class="n">ι</span> <span class="bp">→</span> <span class="n">W</span><span class="o">)</span> <span class="bp">≃ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="o">(</span><span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span><span class="o">))</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">B.constr</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">W</span><span class="o">)</span><span class="w"> </span><span class="bp">≃ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="o">))</span> <span class="k">#check</span> <span class="o">(</span><span class="n">B.constr</span> <span class="n">K</span> <span class="n">u</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">B.constr</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="o">)</span> <span class="kd">example</span> <span class="o">(</span><span class="n">i</span> <span class="o">:</span> <span class="n">ι</span><span class="o">)</span> <span class="o">:</span> <span class="n">B.constr</span> <span class="n">K</span> <span class="n">u</span> <span class="o">(</span><span class="n">B</span> <span class="n">i</span><span class="o">)</span> <span class="bp">=</span> <span class="n">u</span> <span class="n">i</span> <span class="o">:=</span> <span class="n">B.constr_basis</span> <span class="n">K</span> <span class="n">u</span> <span class="n">i</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">i</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">B.constr</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="o">(</span><span class="n">B</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">B.constr_basis</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">i</span> </pre></div> </div> <p>This property is indeed characteristic because linear maps are determined by their values on bases:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="n">ψ</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">i</span><span class="o">,</span> <span class="n">φ</span> <span class="o">(</span><span class="n">B</span> <span class="n">i</span><span class="o">)</span> <span class="bp">=</span> <span class="n">ψ</span> <span class="o">(</span><span class="n">B</span> <span class="n">i</span><span class="o">))</span> <span class="o">:</span> <span class="n">φ</span> <span class="bp">=</span> <span class="n">ψ</span> <span class="o">:=</span> <span class="n">B.ext</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="n">ψ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="o">(</span><span class="n">B</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">ψ</span><span class="w"> </span><span class="o">(</span><span class="n">B</span><span class="w"> </span><span class="n">i</span><span class="o">))</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">ψ</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">B.ext</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>If we also have a basis <code class="docutils literal notranslate"><span class="pre">B'</span></code> on the target space then we can identify linear maps with matrices. This identification is a <code class="docutils literal notranslate"><span class="pre">K</span></code>-linear isomorphism.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">ι'</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">(</span><span class="n">B'</span> <span class="o">:</span> <span class="n">Basis</span> <span class="n">ι'</span> <span class="n">K</span> <span class="n">W</span><span class="o">)</span> <span class="o">[</span><span class="n">Fintype</span> <span class="n">ι</span><span class="o">]</span> <span class="o">[</span><span class="n">DecidableEq</span> <span class="n">ι</span><span class="o">]</span> <span class="o">[</span><span class="n">Fintype</span> <span class="n">ι'</span><span class="o">]</span> <span class="o">[</span><span class="n">DecidableEq</span> <span class="n">ι'</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">ι'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">B'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Basis</span><span class="w"> </span><span class="n">ι'</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">W</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">Fintype</span><span class="w"> </span><span class="n">ι</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">DecidableEq</span><span class="w"> </span><span class="n">ι</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">Fintype</span><span class="w"> </span><span class="n">ι'</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">DecidableEq</span><span class="w"> </span><span class="n">ι'</span><span class="o">]</span> <span class="kn">open</span> <span class="n">LinearMap</span> <span class="kn">open</span><span class="w"> </span><span class="n">LinearMap</span> <span class="k">#check</span> <span class="o">(</span><span class="n">toMatrix</span> <span class="n">B</span> <span class="n">B'</span> <span class="o">:</span> <span class="o">(</span><span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span><span class="o">)</span> <span class="bp">≃ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">Matrix</span> <span class="n">ι'</span> <span class="n">ι</span> <span class="n">K</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">toMatrix</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="n">B'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="o">)</span><span class="w"> </span><span class="bp">≃ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">Matrix</span><span class="w"> </span><span class="n">ι'</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="n">K</span><span class="o">)</span> <span class="kn">open</span> <span class="n">Matrix</span> <span class="c1">-- get access to the ``*ᵥ`` notation for multiplication between matrices and vectors.</span> <span class="kn">open</span><span class="w"> </span><span class="n">Matrix</span><span class="w"> </span><span class="c1">-- get access to the ``*ᵥ`` notation for multiplication between matrices and vectors.</span> <span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span><span class="o">)</span> <span class="o">(</span><span class="n">v</span> <span class="o">:</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">toMatrix</span> <span class="n">B</span> <span class="n">B'</span> <span class="n">φ</span><span class="o">)</span> <span class="bp">*ᵥ</span> <span class="o">(</span><span class="n">B.repr</span> <span class="n">v</span><span class="o">)</span> <span class="bp">=</span> <span class="n">B'.repr</span> <span class="o">(</span><span class="n">φ</span> <span class="n">v</span><span class="o">)</span> <span class="o">:=</span> <span class="n">toMatrix_mulVec_repr</span> <span class="n">B</span> <span class="n">B'</span> <span class="n">φ</span> <span class="n">v</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">v</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">toMatrix</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="n">B'</span><span class="w"> </span><span class="n">φ</span><span class="o">)</span><span class="w"> </span><span class="bp">*ᵥ</span><span class="w"> </span><span class="o">(</span><span class="n">B.repr</span><span class="w"> </span><span class="n">v</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">B'.repr</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="n">v</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">toMatrix_mulVec_repr</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="n">B'</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">v</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">ι''</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">(</span><span class="n">B''</span> <span class="o">:</span> <span class="n">Basis</span> <span class="n">ι''</span> <span class="n">K</span> <span class="n">W</span><span class="o">)</span> <span class="o">[</span><span class="n">Fintype</span> <span class="n">ι''</span><span class="o">]</span> <span class="o">[</span><span class="n">DecidableEq</span> <span class="n">ι''</span><span class="o">]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">ι''</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">B''</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Basis</span><span class="w"> </span><span class="n">ι''</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">W</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">Fintype</span><span class="w"> </span><span class="n">ι''</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">DecidableEq</span><span class="w"> </span><span class="n">ι''</span><span class="o">]</span> <span class="kd">example</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">V</span> <span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span> <span class="n">W</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">toMatrix</span> <span class="n">B</span> <span class="n">B''</span> <span class="n">φ</span><span class="o">)</span> <span class="bp">=</span> <span class="o">(</span><span class="n">toMatrix</span> <span class="n">B'</span> <span class="n">B''</span> <span class="bp">.</span><span class="n">id</span><span class="o">)</span> <span class="bp">*</span> <span class="o">(</span><span class="n">toMatrix</span> <span class="n">B</span> <span class="n">B'</span> <span class="n">φ</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">→ₗ</span><span class="o">[</span><span class="n">K</span><span class="o">]</span><span class="w"> </span><span class="n">W</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">toMatrix</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="n">B''</span><span class="w"> </span><span class="n">φ</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">toMatrix</span><span class="w"> </span><span class="n">B'</span><span class="w"> </span><span class="n">B''</span><span class="w"> </span><span class="bp">.</span><span class="n">id</span><span class="o">)</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="o">(</span><span class="n">toMatrix</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="n">B'</span><span class="w"> </span><span class="n">φ</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">simp</span> <span class="kd">end</span> </pre></div>
-
@@ -1077,25 +1078,25 @@ This would then need to be complemented using that bases all have isomorphic indexing types toget the full result.</p> <p>Of course Mathlib already knows this, and <code class="docutils literal notranslate"><span class="pre">simp</span></code> can close the goal immediately, so you shouldn’t use it too soon, but rather use the provided lemmas.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">Module</span> <span class="n">LinearMap</span> <span class="n">Matrix</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">Module</span><span class="w"> </span><span class="n">LinearMap</span><span class="w"> </span><span class="n">Matrix</span> <span class="c1">-- Some lemmas coming from the fact that `LinearMap.toMatrix` is an algebra morphism.</span> <span class="k">#check</span> <span class="n">toMatrix_comp</span> <span class="k">#check</span> <span class="n">id_comp</span> <span class="k">#check</span> <span class="n">comp_id</span> <span class="k">#check</span> <span class="n">toMatrix_id</span> <span class="k">#check</span><span class="w"> </span><span class="n">toMatrix_comp</span> <span class="k">#check</span><span class="w"> </span><span class="n">id_comp</span> <span class="k">#check</span><span class="w"> </span><span class="n">comp_id</span> <span class="k">#check</span><span class="w"> </span><span class="n">toMatrix_id</span> <span class="c1">-- Some lemmas coming from the fact that ``Matrix.det`` is a multiplicative monoid morphism.</span> <span class="k">#check</span> <span class="n">Matrix.det_mul</span> <span class="k">#check</span> <span class="n">Matrix.det_one</span> <span class="k">#check</span><span class="w"> </span><span class="n">Matrix.det_mul</span> <span class="k">#check</span><span class="w"> </span><span class="n">Matrix.det_one</span> <span class="kd">example</span> <span class="o">[</span><span class="n">Fintype</span> <span class="n">ι</span><span class="o">]</span> <span class="o">(</span><span class="n">B'</span> <span class="o">:</span> <span class="n">Basis</span> <span class="n">ι</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">(</span><span class="n">φ</span> <span class="o">:</span> <span class="n">End</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="n">toMatrix</span> <span class="n">B</span> <span class="n">B</span> <span class="n">φ</span><span class="o">)</span><span class="bp">.</span><span class="n">det</span> <span class="bp">=</span> <span class="o">(</span><span class="n">toMatrix</span> <span class="n">B'</span> <span class="n">B'</span> <span class="n">φ</span><span class="o">)</span><span class="bp">.</span><span class="n">det</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">set</span> <span class="n">M</span> <span class="o">:=</span> <span class="n">toMatrix</span> <span class="n">B</span> <span class="n">B</span> <span class="n">φ</span> <span class="n">set</span> <span class="n">M'</span> <span class="o">:=</span> <span class="n">toMatrix</span> <span class="n">B'</span> <span class="n">B'</span> <span class="n">φ</span> <span class="n">set</span> <span class="n">P</span> <span class="o">:=</span> <span class="o">(</span><span class="n">toMatrix</span> <span class="n">B</span> <span class="n">B'</span><span class="o">)</span> <span class="n">LinearMap.id</span> <span class="n">set</span> <span class="n">P'</span> <span class="o">:=</span> <span class="o">(</span><span class="n">toMatrix</span> <span class="n">B'</span> <span class="n">B</span><span class="o">)</span> <span class="n">LinearMap.id</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">Fintype</span><span class="w"> </span><span class="n">ι</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">B'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Basis</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">End</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="o">(</span><span class="n">toMatrix</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="n">φ</span><span class="o">)</span><span class="bp">.</span><span class="n">det</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">toMatrix</span><span class="w"> </span><span class="n">B'</span><span class="w"> </span><span class="n">B'</span><span class="w"> </span><span class="n">φ</span><span class="o">)</span><span class="bp">.</span><span class="n">det</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">set</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">toMatrix</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="n">φ</span> <span class="w"> </span><span class="n">set</span><span class="w"> </span><span class="n">M'</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">toMatrix</span><span class="w"> </span><span class="n">B'</span><span class="w"> </span><span class="n">B'</span><span class="w"> </span><span class="n">φ</span> <span class="w"> </span><span class="n">set</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="n">toMatrix</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="n">B'</span><span class="o">)</span><span class="w"> </span><span class="n">LinearMap.id</span> <span class="w"> </span><span class="n">set</span><span class="w"> </span><span class="n">P'</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">(</span><span class="n">toMatrix</span><span class="w"> </span><span class="n">B'</span><span class="w"> </span><span class="n">B</span><span class="o">)</span><span class="w"> </span><span class="n">LinearMap.id</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">end</span> </pre></div> </div>
-
@@ -1109,19 +1110,19 @@ For such spaces we expect a dimension which is a natural number.This is <code class="docutils literal notranslate"><span class="pre">Module.finrank</span></code>. It takes the base field as an explicit argument since a given abelian group can be a vector space over different fields.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span> <span class="k">#check</span> <span class="o">(</span><span class="n">Module.finrank</span> <span class="n">K</span> <span class="n">V</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">Module.finrank</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span> <span class="c1">-- `Fin n → K` is the archetypical space with dimension `n` over `K`.</span> <span class="kd">example</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:</span> <span class="n">Module.finrank</span> <span class="n">K</span> <span class="o">(</span><span class="n">Fin</span> <span class="n">n</span> <span class="bp">→</span> <span class="n">K</span><span class="o">)</span> <span class="bp">=</span> <span class="n">n</span> <span class="o">:=</span> <span class="n">Module.finrank_fin_fun</span> <span class="n">K</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Module.finrank</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="o">(</span><span class="n">Fin</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">K</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Module.finrank_fin_fun</span><span class="w"> </span><span class="n">K</span> <span class="c1">-- Seen as a vector space over itself, `ℂ` has dimension one.</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">Module.finrank</span> <span class="n">ℂ</span> <span class="n">ℂ</span> <span class="bp">=</span> <span class="mi">1</span> <span class="o">:=</span> <span class="n">Module.finrank_self</span> <span class="n">ℂ</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Module.finrank</span><span class="w"> </span><span class="n">ℂ</span><span class="w"> </span><span class="n">ℂ</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Module.finrank_self</span><span class="w"> </span><span class="n">ℂ</span> <span class="c1">-- But as a real vector space it has dimension two.</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">Module.finrank</span> <span class="n">ℝ</span> <span class="n">ℂ</span> <span class="bp">=</span> <span class="mi">2</span> <span class="o">:=</span> <span class="n">Complex.finrank_real_complex</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Module.finrank</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="n">ℂ</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Complex.finrank_real_complex</span> </pre></div> </div> <p>Note that <code class="docutils literal notranslate"><span class="pre">Module.finrank</span></code> is defined for any vector space. It returns
-
@@ -1129,8 +1130,8 @@ zero for infinite dimensional vector spaces, just as division by zero returns zero.</p><p>Of course many lemmas require a finite dimension assumption. This is the role of the <code class="docutils literal notranslate"><span class="pre">FiniteDimensional</span></code> typeclass. For instance, think about how the next example fails without this assumption.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">[</span><span class="n">FiniteDimensional</span> <span class="n">K</span> <span class="n">V</span><span class="o">]</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">Module.finrank</span> <span class="n">K</span> <span class="n">V</span> <span class="bp">↔</span> <span class="n">Nontrivial</span> <span class="n">V</span> <span class="o">:=</span> <span class="n">Module.finrank_pos_iff</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">FiniteDimensional</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">Module.finrank</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">Nontrivial</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Module.finrank_pos_iff</span> </pre></div> </div> <p>In the above statement, <code class="docutils literal notranslate"><span class="pre">Nontrivial</span> <span class="pre">V</span></code> means <code class="docutils literal notranslate"><span class="pre">V</span></code> has at least two different elements.
-
@@ -1139,44 +1140,44 @@ This is fine when using it from left to right, but not when using it from right to leftbecause Lean has no way to guess <code class="docutils literal notranslate"><span class="pre">K</span></code> from the statement <code class="docutils literal notranslate"><span class="pre">Nontrivial</span> <span class="pre">V</span></code>. In that case it is useful to use the name argument syntax, after checking that the lemma is stated over a ring named <code class="docutils literal notranslate"><span class="pre">R</span></code>. So we can write:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">[</span><span class="n">FiniteDimensional</span> <span class="n">K</span> <span class="n">V</span><span class="o">]</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">Module.finrank</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">:</span> <span class="n">Nontrivial</span> <span class="n">V</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="o">(</span><span class="n">Module.finrank_pos_iff</span> <span class="o">(</span><span class="n">R</span> <span class="o">:=</span> <span class="n">K</span><span class="o">))</span><span class="bp">.</span><span class="mi">1</span> <span class="n">exact</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">FiniteDimensional</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">Module.finrank</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Nontrivial</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="o">(</span><span class="n">Module.finrank_pos_iff</span><span class="w"> </span><span class="o">(</span><span class="n">R</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">K</span><span class="o">))</span><span class="bp">.</span><span class="mi">1</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>The above spelling is strange because we already have <code class="docutils literal notranslate"><span class="pre">h</span></code> as an assumption, so we could just as well give the full proof <code class="docutils literal notranslate"><span class="pre">Module.finrank_pos_iff.1</span> <span class="pre">h</span></code> but it is good to know for more complicated cases.</p> <p>By definition, <code class="docutils literal notranslate"><span class="pre">FiniteDimensional</span> <span class="pre">K</span> <span class="pre">V</span></code> can be read from any basis.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">ι</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">(</span><span class="n">B</span> <span class="o">:</span> <span class="n">Basis</span> <span class="n">ι</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">ι</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">B</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Basis</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span> <span class="kd">example</span> <span class="o">[</span><span class="n">Finite</span> <span class="n">ι</span><span class="o">]</span> <span class="o">:</span> <span class="n">FiniteDimensional</span> <span class="n">K</span> <span class="n">V</span> <span class="o">:=</span> <span class="n">FiniteDimensional.of_fintype_basis</span> <span class="n">B</span> <span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">Finite</span><span class="w"> </span><span class="n">ι</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">FiniteDimensional</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">FiniteDimensional.of_fintype_basis</span><span class="w"> </span><span class="n">B</span> <span class="kd">example</span> <span class="o">[</span><span class="n">FiniteDimensional</span> <span class="n">K</span> <span class="n">V</span><span class="o">]</span> <span class="o">:</span> <span class="n">Finite</span> <span class="n">ι</span> <span class="o">:=</span> <span class="o">(</span><span class="n">FiniteDimensional.fintypeBasisIndex</span> <span class="n">B</span><span class="o">)</span><span class="bp">.</span><span class="n">finite</span> <span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">FiniteDimensional</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Finite</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">(</span><span class="n">FiniteDimensional.fintypeBasisIndex</span><span class="w"> </span><span class="n">B</span><span class="o">)</span><span class="bp">.</span><span class="n">finite</span> <span class="kd">end</span> </pre></div> </div> <p>Using that the subtype corresponding to a linear subspace has a vector space structure, we can talk about the dimension of a subspace.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span> <span class="kd">variable</span> <span class="o">(</span><span class="n">E</span> <span class="n">F</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">[</span><span class="n">FiniteDimensional</span> <span class="n">K</span> <span class="n">V</span><span class="o">]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">E</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">FiniteDimensional</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">]</span> <span class="kn">open</span> <span class="n">Module</span> <span class="kn">open</span><span class="w"> </span><span class="n">Module</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">finrank</span> <span class="n">K</span> <span class="o">(</span><span class="n">E</span> <span class="bp">⊔</span> <span class="n">F</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="bp">+</span> <span class="n">finrank</span> <span class="n">K</span> <span class="o">(</span><span class="n">E</span> <span class="bp">⊓</span> <span class="n">F</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="bp">=</span> <span class="n">finrank</span> <span class="n">K</span> <span class="n">E</span> <span class="bp">+</span> <span class="n">finrank</span> <span class="n">K</span> <span class="n">F</span> <span class="o">:=</span> <span class="n">Submodule.finrank_sup_add_finrank_inf_eq</span> <span class="n">E</span> <span class="n">F</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">finrank</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="o">(</span><span class="n">E</span><span class="w"> </span><span class="bp">⊔</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">finrank</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="o">(</span><span class="n">E</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span> <span class="w"> </span><span class="n">finrank</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">finrank</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Submodule.finrank_sup_add_finrank_inf_eq</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="n">F</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">finrank</span> <span class="n">K</span> <span class="n">E</span> <span class="bp">≤</span> <span class="n">finrank</span> <span class="n">K</span> <span class="n">V</span> <span class="o">:=</span> <span class="n">Submodule.finrank_le</span> <span class="n">E</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">finrank</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">finrank</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">Submodule.finrank_le</span><span class="w"> </span><span class="n">E</span> </pre></div> </div> <p>In the first statement above, the purpose of the type ascriptions is to make sure that coercion to <code class="docutils literal notranslate"><span class="pre">Type*</span></code> does not trigger too early.</p> <p>We are now ready for an exercise about <code class="docutils literal notranslate"><span class="pre">finrank</span></code> and subspaces.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">finrank</span> <span class="n">K</span> <span class="n">V</span> <span class="bp"><</span> <span class="n">finrank</span> <span class="n">K</span> <span class="n">E</span> <span class="bp">+</span> <span class="n">finrank</span> <span class="n">K</span> <span class="n">F</span><span class="o">)</span> <span class="o">:</span> <span class="n">Nontrivial</span> <span class="o">(</span><span class="n">E</span> <span class="bp">⊓</span> <span class="n">F</span> <span class="o">:</span> <span class="n">Submodule</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">finrank</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">finrank</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">finrank</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Nontrivial</span><span class="w"> </span><span class="o">(</span><span class="n">E</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Submodule</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="kd">end</span> </pre></div> </div>
-
@@ -1215,28 +1216,28 @@ a basis of <code class="docutils literal notranslate"><span class="pre">V</span></code>.So instead it is defined as the supremum <code class="docutils literal notranslate"><span class="pre">Module.rank</span> <span class="pre">K</span> <span class="pre">V</span></code> of cardinals of all linearly independent sets in <code class="docutils literal notranslate"><span class="pre">V</span></code>. If <code class="docutils literal notranslate"><span class="pre">V</span></code> has universe level <code class="docutils literal notranslate"><span class="pre">u</span></code> then its rank has type <code class="docutils literal notranslate"><span class="pre">Cardinal.{u}</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="n">V</span> <span class="c1">-- Type u_2</span> <span class="k">#check</span> <span class="n">Module.rank</span> <span class="n">K</span> <span class="n">V</span> <span class="c1">-- Cardinal.{u_2}</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="c1">-- Type u_2</span> <span class="k">#check</span><span class="w"> </span><span class="n">Module.rank</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="c1">-- Cardinal.{u_2}</span> </pre></div> </div> <p>One can still relate this definition to bases. Indeed there is also a commutative <code class="docutils literal notranslate"><span class="pre">max</span></code> operation on universe levels, and given two universe levels <code class="docutils literal notranslate"><span class="pre">u</span></code> and <code class="docutils literal notranslate"><span class="pre">v</span></code> there is an operation <code class="docutils literal notranslate"><span class="pre">Cardinal.lift.{u,</span> <span class="pre">v}</span> <span class="pre">:</span> <span class="pre">Cardinal.{v}</span> <span class="pre">→</span> <span class="pre">Cardinal.{max</span> <span class="pre">v</span> <span class="pre">u}</span></code> that allows to put cardinals in a common universe and state the dimension theorem.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">universe</span> <span class="n">u</span> <span class="n">v</span> <span class="c1">-- `u` and `v` will denote universe levels</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">universe</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="c1">-- `u` and `v` will denote universe levels</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">ι</span> <span class="o">:</span> <span class="kt">Type</span> <span class="n">u</span><span class="o">}</span> <span class="o">(</span><span class="n">B</span> <span class="o">:</span> <span class="n">Basis</span> <span class="n">ι</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="o">{</span><span class="n">ι'</span> <span class="o">:</span> <span class="kt">Type</span> <span class="n">v</span><span class="o">}</span> <span class="o">(</span><span class="n">B'</span> <span class="o">:</span> <span class="n">Basis</span> <span class="n">ι'</span> <span class="n">K</span> <span class="n">V</span><span class="o">)</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">ι</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="w"> </span><span class="n">u</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">B</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Basis</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span> <span class="w"> </span><span class="o">{</span><span class="n">ι'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="w"> </span><span class="n">v</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">B'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Basis</span><span class="w"> </span><span class="n">ι'</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">)</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">Cardinal.lift.</span><span class="o">{</span><span class="n">v</span><span class="o">,</span> <span class="n">u</span><span class="o">}</span> <span class="o">(</span><span class="bp">.</span><span class="n">mk</span> <span class="n">ι</span><span class="o">)</span> <span class="bp">=</span> <span class="n">Cardinal.lift.</span><span class="o">{</span><span class="n">u</span><span class="o">,</span> <span class="n">v</span><span class="o">}</span> <span class="o">(</span><span class="bp">.</span><span class="n">mk</span> <span class="n">ι'</span><span class="o">)</span> <span class="o">:=</span> <span class="n">mk_eq_mk_of_basis</span> <span class="n">B</span> <span class="n">B'</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Cardinal.lift</span><span class="bp">.</span><span class="o">{</span><span class="n">v</span><span class="o">,</span><span class="w"> </span><span class="n">u</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="bp">.</span><span class="n">mk</span><span class="w"> </span><span class="n">ι</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">Cardinal.lift</span><span class="bp">.</span><span class="o">{</span><span class="n">u</span><span class="o">,</span><span class="w"> </span><span class="n">v</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="bp">.</span><span class="n">mk</span><span class="w"> </span><span class="n">ι'</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">mk_eq_mk_of_basis</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="n">B'</span> </pre></div> </div> <p>We can relate the finite dimensional case to this discussion using the coercion from natural numbers to finite cardinals (or more precisely the finite cardinals which live in <code class="docutils literal notranslate"><span class="pre">Cardinal.{v}</span></code> where <code class="docutils literal notranslate"><span class="pre">v</span></code> is the universe level of <code class="docutils literal notranslate"><span class="pre">V</span></code>).</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">[</span><span class="n">FiniteDimensional</span> <span class="n">K</span> <span class="n">V</span><span class="o">]</span> <span class="o">:</span> <span class="o">(</span><span class="n">Module.finrank</span> <span class="n">K</span> <span class="n">V</span> <span class="o">:</span> <span class="n">Cardinal</span><span class="o">)</span> <span class="bp">=</span> <span class="n">Module.rank</span> <span class="n">K</span> <span class="n">V</span> <span class="o">:=</span> <span class="n">Module.finrank_eq_rank</span> <span class="n">K</span> <span class="n">V</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">FiniteDimensional</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="o">]</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="o">(</span><span class="n">Module.finrank</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Cardinal</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">Module.rank</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Module.finrank_eq_rank</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="n">V</span> </pre></div> </div> </section>
-
-
-
@@ -1,3 +1,5 @@<!DOCTYPE html> <html class="writer-html5" lang="en" data-content_root="./"> <head>
-
@@ -6,18 +8,17 @@<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>10. Topology — Mathematics in Lean 0.1 documentation</title> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=80d5e7a1" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=86f27845" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" /> <link rel="stylesheet" type="text/css" href="_static/css/custom.css?v=0731ccc3" /> <link rel="shortcut icon" href="_static/favicon.ico"/> <script src="_static/jquery.js?v=8dae8fb0"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=888ff710"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> <script src="_static/jquery.js?v=5d32c60e"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=9bcbadda"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> <script src="_static/js/theme.js"></script> <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" />
-
@@ -215,21 +216,21 @@ One manifestation of this view is that we can associate to any <code class="docutils literal notranslate"><span class="pre">s</span> <span class="pre">:</span> <span class="pre">Set</span> <span class="pre">X</span></code> the so-called <em>principal filter</em>consisting of all sets that contain <code class="docutils literal notranslate"><span class="pre">s</span></code>. This definition is already in Mathlib and has a notation <code class="docutils literal notranslate"><span class="pre">𝓟</span></code> (localized in the <code class="docutils literal notranslate"><span class="pre">Filter</span></code> namespace). For the purpose of demonstration, we ask you to take this opportunity to work out the definition here.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">principal</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">(</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">α</span><span class="o">)</span> <span class="o">:</span> <span class="n">Filter</span> <span class="n">α</span> <span class="n">where</span> <span class="n">sets</span> <span class="o">:=</span> <span class="o">{</span> <span class="n">t</span> <span class="bp">|</span> <span class="n">s</span> <span class="bp">⊆</span> <span class="n">t</span> <span class="o">}</span> <span class="n">univ_sets</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">sets_of_superset</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">inter_sets</span> <span class="o">:=</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">principal</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">α</span> <span class="w"> </span><span class="n">where</span> <span class="w"> </span><span class="n">sets</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">}</span> <span class="w"> </span><span class="n">univ_sets</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">sets_of_superset</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">inter_sets</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>For our second example, we ask you to define the filter <code class="docutils literal notranslate"><span class="pre">atTop</span> <span class="pre">:</span> <span class="pre">Filter</span> <span class="pre">ℕ</span></code>. (We could use any type with a preorder instead of <code class="docutils literal notranslate"><span class="pre">ℕ</span></code>.)</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">Filter</span> <span class="n">ℕ</span> <span class="o">:=</span> <span class="o">{</span> <span class="n">sets</span> <span class="o">:=</span> <span class="o">{</span> <span class="n">s</span> <span class="bp">|</span> <span class="bp">∃</span> <span class="n">a</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">b</span><span class="o">,</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">b</span> <span class="bp">→</span> <span class="n">b</span> <span class="bp">∈</span> <span class="n">s</span> <span class="o">}</span> <span class="n">univ_sets</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">sets_of_superset</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">inter_sets</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="o">}</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">sets</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">}</span> <span class="w"> </span><span class="n">univ_sets</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">sets_of_superset</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">inter_sets</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span><span class="w"> </span><span class="o">}</span> </pre></div> </div> <p>We can also directly define the filter <code class="docutils literal notranslate"><span class="pre">𝓝</span> <span class="pre">x</span></code> of neighborhoods of any <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">:</span> <span class="pre">ℝ</span></code>.
-
@@ -240,8 +241,8 @@ (This is notion of a neighborhood is only a special case of a more general construction in Mathlib.)</p><p>With these examples, we can already define what is means for a function <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">:</span> <span class="pre">X</span> <span class="pre">→</span> <span class="pre">Y</span></code> to converge to some <code class="docutils literal notranslate"><span class="pre">G</span> <span class="pre">:</span> <span class="pre">Filter</span> <span class="pre">Y</span></code> along some <code class="docutils literal notranslate"><span class="pre">F</span> <span class="pre">:</span> <span class="pre">Filter</span> <span class="pre">X</span></code>, as follows:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">Tendsto₁</span> <span class="o">{</span><span class="n">X</span> <span class="n">Y</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">)</span> <span class="o">(</span><span class="n">F</span> <span class="o">:</span> <span class="n">Filter</span> <span class="n">X</span><span class="o">)</span> <span class="o">(</span><span class="n">G</span> <span class="o">:</span> <span class="n">Filter</span> <span class="n">Y</span><span class="o">)</span> <span class="o">:=</span> <span class="bp">∀</span> <span class="n">V</span> <span class="bp">∈</span> <span class="n">G</span><span class="o">,</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="n">V</span> <span class="bp">∈</span> <span class="n">F</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">Tendsto₁</span><span class="w"> </span><span class="o">{</span><span class="n">X</span><span class="w"> </span><span class="n">Y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">Y</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">G</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">F</span> </pre></div> </div> <p>When <code class="docutils literal notranslate"><span class="pre">X</span></code> is <code class="docutils literal notranslate"><span class="pre">ℕ</span></code> and <code class="docutils literal notranslate"><span class="pre">Y</span></code> is <code class="docutils literal notranslate"><span class="pre">ℝ</span></code>, <code class="docutils literal notranslate"><span class="pre">Tendsto₁</span> <span class="pre">u</span> <span class="pre">atTop</span> <span class="pre">(𝓝</span> <span class="pre">x)</span></code> is equivalent to saying that the sequence <code class="docutils literal notranslate"><span class="pre">u</span> <span class="pre">:</span> <span class="pre">ℕ</span> <span class="pre">→</span> <span class="pre">ℝ</span></code>
-
@@ -261,12 +262,12 @@ In this examples file we’ve opened the <code class="docutils literal notranslate"><span class="pre">Filter</span></code> namespace so that<code class="docutils literal notranslate"><span class="pre">Filter.map</span></code> can be written as <code class="docutils literal notranslate"><span class="pre">map</span></code>. This means that we can rewrite the definition of <code class="docutils literal notranslate"><span class="pre">Tendsto</span></code> using the order relation on <code class="docutils literal notranslate"><span class="pre">Filter</span> <span class="pre">Y</span></code>, which is reversed inclusion of the set of members. In other words, given <code class="docutils literal notranslate"><span class="pre">G</span> <span class="pre">H</span> <span class="pre">:</span> <span class="pre">Filter</span> <span class="pre">Y</span></code>, we have <code class="docutils literal notranslate"><span class="pre">G</span> <span class="pre">≤</span> <span class="pre">H</span> <span class="pre">↔</span> <span class="pre">∀</span> <span class="pre">V</span> <span class="pre">:</span> <span class="pre">Set</span> <span class="pre">Y,</span> <span class="pre">V</span> <span class="pre">∈</span> <span class="pre">H</span> <span class="pre">→</span> <span class="pre">V</span> <span class="pre">∈</span> <span class="pre">G</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span> <span class="n">Tendsto₂</span> <span class="o">{</span><span class="n">X</span> <span class="n">Y</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">)</span> <span class="o">(</span><span class="n">F</span> <span class="o">:</span> <span class="n">Filter</span> <span class="n">X</span><span class="o">)</span> <span class="o">(</span><span class="n">G</span> <span class="o">:</span> <span class="n">Filter</span> <span class="n">Y</span><span class="o">)</span> <span class="o">:=</span> <span class="n">map</span> <span class="n">f</span> <span class="n">F</span> <span class="bp">≤</span> <span class="n">G</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">def</span><span class="w"> </span><span class="n">Tendsto₂</span><span class="w"> </span><span class="o">{</span><span class="n">X</span><span class="w"> </span><span class="n">Y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">Y</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">map</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">G</span> <span class="kd">example</span> <span class="o">{</span><span class="n">X</span> <span class="n">Y</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">)</span> <span class="o">(</span><span class="n">F</span> <span class="o">:</span> <span class="n">Filter</span> <span class="n">X</span><span class="o">)</span> <span class="o">(</span><span class="n">G</span> <span class="o">:</span> <span class="n">Filter</span> <span class="n">Y</span><span class="o">)</span> <span class="o">:</span> <span class="n">Tendsto₂</span> <span class="n">f</span> <span class="n">F</span> <span class="n">G</span> <span class="bp">↔</span> <span class="n">Tendsto₁</span> <span class="n">f</span> <span class="n">F</span> <span class="n">G</span> <span class="o">:=</span> <span class="n">Iff.rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">X</span><span class="w"> </span><span class="n">Y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">Y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Tendsto₂</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">Tendsto₁</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Iff.rfl</span> </pre></div> </div> <p>It may seem that the order relation on filters is backward. But recall that we can view filters on <code class="docutils literal notranslate"><span class="pre">X</span></code> as
-
@@ -282,11 +283,11 @@ <p>As promised, the definition of <code class="docutils literal notranslate"><span class="pre">Tendsto₂</span></code> does not exhibit any quantifiers or sets.It also leverages the algebraic properties of the pushforward operation. First, each <code class="docutils literal notranslate"><span class="pre">Filter.map</span> <span class="pre">f</span></code> is monotone. And, second, <code class="docutils literal notranslate"><span class="pre">Filter.map</span></code> is compatible with composition.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="o">(</span><span class="bp">@</span><span class="n">Filter.map_mono</span> <span class="o">:</span> <span class="bp">∀</span> <span class="o">{</span><span class="n">α</span> <span class="n">β</span><span class="o">}</span> <span class="o">{</span><span class="n">m</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">β</span><span class="o">},</span> <span class="n">Monotone</span> <span class="o">(</span><span class="n">map</span> <span class="n">m</span><span class="o">))</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="bp">@</span><span class="n">Filter.map_mono</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="n">β</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">m</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">β</span><span class="o">},</span><span class="w"> </span><span class="n">Monotone</span><span class="w"> </span><span class="o">(</span><span class="n">map</span><span class="w"> </span><span class="n">m</span><span class="o">))</span> <span class="k">#check</span> <span class="o">(</span><span class="bp">@</span><span class="n">Filter.map_map</span> <span class="o">:</span> <span class="bp">∀</span> <span class="o">{</span><span class="n">α</span> <span class="n">β</span> <span class="n">γ</span><span class="o">}</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">Filter</span> <span class="n">α</span><span class="o">}</span> <span class="o">{</span><span class="n">m</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">β</span><span class="o">}</span> <span class="o">{</span><span class="n">m'</span> <span class="o">:</span> <span class="n">β</span> <span class="bp">→</span> <span class="n">γ</span><span class="o">},</span> <span class="n">map</span> <span class="n">m'</span> <span class="o">(</span><span class="n">map</span> <span class="n">m</span> <span class="n">f</span><span class="o">)</span> <span class="bp">=</span> <span class="n">map</span> <span class="o">(</span><span class="n">m'</span> <span class="bp">∘</span> <span class="n">m</span><span class="o">)</span> <span class="n">f</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="bp">@</span><span class="n">Filter.map_map</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="n">γ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">α</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">m</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">β</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">m'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">γ</span><span class="o">},</span><span class="w"> </span><span class="n">map</span><span class="w"> </span><span class="n">m'</span><span class="w"> </span><span class="o">(</span><span class="n">map</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">map</span><span class="w"> </span><span class="o">(</span><span class="n">m'</span><span class="w"> </span><span class="bp">∘</span><span class="w"> </span><span class="n">m</span><span class="o">)</span><span class="w"> </span><span class="n">f</span><span class="o">)</span> </pre></div> </div> <p>Together these two properties allow us to prove that limits compose, yielding in one shot all 512 variants
-
@@ -295,9 +296,9 @@ You can practice proving the following statement using either the definitionof <code class="docutils literal notranslate"><span class="pre">Tendsto₁</span></code> in terms of the universal quantifier or the algebraic definition, together with the two lemmas above.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">X</span> <span class="n">Y</span> <span class="n">Z</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">{</span><span class="n">F</span> <span class="o">:</span> <span class="n">Filter</span> <span class="n">X</span><span class="o">}</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="n">Filter</span> <span class="n">Y</span><span class="o">}</span> <span class="o">{</span><span class="n">H</span> <span class="o">:</span> <span class="n">Filter</span> <span class="n">Z</span><span class="o">}</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">}</span> <span class="o">{</span><span class="n">g</span> <span class="o">:</span> <span class="n">Y</span> <span class="bp">→</span> <span class="n">Z</span><span class="o">}</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">Tendsto₁</span> <span class="n">f</span> <span class="n">F</span> <span class="n">G</span><span class="o">)</span> <span class="o">(</span><span class="n">hg</span> <span class="o">:</span> <span class="n">Tendsto₁</span> <span class="n">g</span> <span class="n">G</span> <span class="n">H</span><span class="o">)</span> <span class="o">:</span> <span class="n">Tendsto₁</span> <span class="o">(</span><span class="n">g</span> <span class="bp">∘</span> <span class="n">f</span><span class="o">)</span> <span class="n">F</span> <span class="n">H</span> <span class="o">:=</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">X</span><span class="w"> </span><span class="n">Y</span><span class="w"> </span><span class="n">Z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">Y</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">Z</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Y</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Z</span><span class="o">}</span> <span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Tendsto₁</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Tendsto₁</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="n">H</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Tendsto₁</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="bp">∘</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>The pushforward construction uses a map to push filters from the map source to the map target.
-
@@ -316,19 +317,19 @@ <p>The <code class="docutils literal notranslate"><span class="pre">comap</span></code> operation can be used to restrict filters to a subtype. For instance, suppose we have <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">:</span> <span class="pre">ℝ</span> <span class="pre">→</span> <span class="pre">ℝ</span></code>,<code class="docutils literal notranslate"><span class="pre">x₀</span> <span class="pre">:</span> <span class="pre">ℝ</span></code> and <code class="docutils literal notranslate"><span class="pre">y₀</span> <span class="pre">:</span> <span class="pre">ℝ</span></code>, and suppose we want to state that <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">x</span></code> approaches <code class="docutils literal notranslate"><span class="pre">y₀</span></code> when <code class="docutils literal notranslate"><span class="pre">x</span></code> approaches <code class="docutils literal notranslate"><span class="pre">x₀</span></code> within the rational numbers. We can pull the filter <code class="docutils literal notranslate"><span class="pre">𝓝</span> <span class="pre">x₀</span></code> back to <code class="docutils literal notranslate"><span class="pre">ℚ</span></code> using the coercion map <code class="docutils literal notranslate"><span class="pre">(↑)</span> <span class="pre">:</span> <span class="pre">ℚ</span> <span class="pre">→</span> <span class="pre">ℝ</span></code> and state <code class="docutils literal notranslate"><span class="pre">Tendsto</span> <span class="pre">(f</span> <span class="pre">∘</span> <span class="pre">(↑)</span> <span class="pre">:</span> <span class="pre">ℚ</span> <span class="pre">→</span> <span class="pre">ℝ)</span> <span class="pre">(comap</span> <span class="pre">(↑)</span> <span class="pre">(𝓝</span> <span class="pre">x₀))</span> <span class="pre">(𝓝</span> <span class="pre">y₀)</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">x₀</span> <span class="n">y₀</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">x₀</span><span class="w"> </span><span class="n">y₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span> <span class="k">#check</span> <span class="n">comap</span> <span class="o">((</span><span class="bp">↑</span><span class="o">)</span> <span class="o">:</span> <span class="n">ℚ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">x₀</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="n">comap</span><span class="w"> </span><span class="o">((</span><span class="bp">↑</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℚ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">x₀</span><span class="o">)</span> <span class="k">#check</span> <span class="n">Tendsto</span> <span class="o">(</span><span class="n">f</span> <span class="bp">∘</span> <span class="o">(</span><span class="bp">↑</span><span class="o">))</span> <span class="o">(</span><span class="n">comap</span> <span class="o">((</span><span class="bp">↑</span><span class="o">)</span> <span class="o">:</span> <span class="n">ℚ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">x₀</span><span class="o">))</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">y₀</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="bp">∘</span><span class="w"> </span><span class="o">(</span><span class="bp">↑</span><span class="o">))</span><span class="w"> </span><span class="o">(</span><span class="n">comap</span><span class="w"> </span><span class="o">((</span><span class="bp">↑</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℚ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">x₀</span><span class="o">))</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">y₀</span><span class="o">)</span> </pre></div> </div> <p>The pullback operation is also compatible with composition, but it is <em>contravariant</em>, which is to say, it reverses the order of the arguments.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="n">β</span> <span class="n">γ</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">(</span><span class="n">F</span> <span class="o">:</span> <span class="n">Filter</span> <span class="n">α</span><span class="o">)</span> <span class="o">{</span><span class="n">m</span> <span class="o">:</span> <span class="n">γ</span> <span class="bp">→</span> <span class="n">β</span><span class="o">}</span> <span class="o">{</span><span class="n">n</span> <span class="o">:</span> <span class="n">β</span> <span class="bp">→</span> <span class="n">α</span><span class="o">}</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="n">γ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">m</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">γ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">β</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span><span class="o">}</span> <span class="k">#check</span> <span class="o">(</span><span class="n">comap_comap</span> <span class="o">:</span> <span class="n">comap</span> <span class="n">m</span> <span class="o">(</span><span class="n">comap</span> <span class="n">n</span> <span class="n">F</span><span class="o">)</span> <span class="bp">=</span> <span class="n">comap</span> <span class="o">(</span><span class="n">n</span> <span class="bp">∘</span> <span class="n">m</span><span class="o">)</span> <span class="n">F</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">comap_comap</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">comap</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">(</span><span class="n">comap</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">comap</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">∘</span><span class="w"> </span><span class="n">m</span><span class="o">)</span><span class="w"> </span><span class="n">F</span><span class="o">)</span> <span class="kd">end</span> </pre></div>
-
@@ -336,8 +337,8 @@ </div><p>Let’s now shift attention to the plane <code class="docutils literal notranslate"><span class="pre">ℝ</span> <span class="pre">×</span> <span class="pre">ℝ</span></code> and try to understand how the neighborhoods of a point <code class="docutils literal notranslate"><span class="pre">(x₀,</span> <span class="pre">y₀)</span></code> are related to <code class="docutils literal notranslate"><span class="pre">𝓝</span> <span class="pre">x₀</span></code> and <code class="docutils literal notranslate"><span class="pre">𝓝</span> <span class="pre">y₀</span></code>. There is a product operation <code class="docutils literal notranslate"><span class="pre">Filter.prod</span> <span class="pre">:</span> <span class="pre">Filter</span> <span class="pre">X</span> <span class="pre">→</span> <span class="pre">Filter</span> <span class="pre">Y</span> <span class="pre">→</span> <span class="pre">Filter</span> <span class="pre">(X</span> <span class="pre">×</span> <span class="pre">Y)</span></code>, denoted by <code class="docutils literal notranslate"><span class="pre">×ˢ</span></code>, which answers this question:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="bp">𝓝</span> <span class="o">(</span><span class="n">x₀</span><span class="o">,</span> <span class="n">y₀</span><span class="o">)</span> <span class="bp">=</span> <span class="bp">𝓝</span> <span class="n">x₀</span> <span class="bp">×ˢ</span> <span class="bp">𝓝</span> <span class="n">y₀</span> <span class="o">:=</span> <span class="n">nhds_prod_eq</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">𝓝</span><span class="w"> </span><span class="o">(</span><span class="n">x₀</span><span class="o">,</span><span class="w"> </span><span class="n">y₀</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">𝓝</span><span class="w"> </span><span class="n">x₀</span><span class="w"> </span><span class="bp">×ˢ</span><span class="w"> </span><span class="n">𝓝</span><span class="w"> </span><span class="n">y₀</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">nhds_prod_eq</span> </pre></div> </div> <p>The product operation is defined in terms of the pullback operation and the <code class="docutils literal notranslate"><span class="pre">inf</span></code> operation:</p>
-
@@ -351,12 +352,12 @@ <p>A lot of proofs in Mathlib use all of the aforementioned structure (<code class="docutils literal notranslate"><span class="pre">map</span></code>, <code class="docutils literal notranslate"><span class="pre">comap</span></code>, <code class="docutils literal notranslate"><span class="pre">inf</span></code>, <code class="docutils literal notranslate"><span class="pre">sup</span></code>, and <code class="docutils literal notranslate"><span class="pre">prod</span></code>)to give algebraic proofs about convergence without ever referring to members of filters. You can practice doing this in a proof of the following lemma, unfolding the definition of <code class="docutils literal notranslate"><span class="pre">Tendsto</span></code> and <code class="docutils literal notranslate"><span class="pre">Filter.prod</span></code> if needed.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="n">le_inf_iff</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="n">le_inf_iff</span> <span class="kd">example</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">ℝ</span> <span class="bp">×</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">x₀</span> <span class="n">y₀</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">Tendsto</span> <span class="n">f</span> <span class="n">atTop</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="o">(</span><span class="n">x₀</span><span class="o">,</span> <span class="n">y₀</span><span class="o">))</span> <span class="bp">↔</span> <span class="n">Tendsto</span> <span class="o">(</span><span class="n">Prod.fst</span> <span class="bp">∘</span> <span class="n">f</span><span class="o">)</span> <span class="n">atTop</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">x₀</span><span class="o">)</span> <span class="bp">∧</span> <span class="n">Tendsto</span> <span class="o">(</span><span class="n">Prod.snd</span> <span class="bp">∘</span> <span class="n">f</span><span class="o">)</span> <span class="n">atTop</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">y₀</span><span class="o">)</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">x₀</span><span class="w"> </span><span class="n">y₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">atTop</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="o">(</span><span class="n">x₀</span><span class="o">,</span><span class="w"> </span><span class="n">y₀</span><span class="o">))</span><span class="w"> </span><span class="bp">↔</span> <span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="o">(</span><span class="n">Prod.fst</span><span class="w"> </span><span class="bp">∘</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="n">atTop</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">x₀</span><span class="o">)</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="o">(</span><span class="n">Prod.snd</span><span class="w"> </span><span class="bp">∘</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="n">atTop</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">y₀</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>The ordered type <code class="docutils literal notranslate"><span class="pre">Filter</span> <span class="pre">X</span></code> is actually a <em>complete</em> lattice,
-
@@ -409,8 +410,8 @@ a predicate on <code class="docutils literal notranslate"><span class="pre">ι</span></code> that selects only some of the values <code class="docutils literal notranslate"><span class="pre">i</span></code> in the indexing type.In the case of <code class="docutils literal notranslate"><span class="pre">𝓝</span> <span class="pre">x₀</span></code>, we want <code class="docutils literal notranslate"><span class="pre">ι</span></code> to be <code class="docutils literal notranslate"><span class="pre">ℝ</span></code>, we write <code class="docutils literal notranslate"><span class="pre">ε</span></code> for <code class="docutils literal notranslate"><span class="pre">i</span></code>, and the predicate should select the positive values of <code class="docutils literal notranslate"><span class="pre">ε</span></code>. So the fact that the sets <code class="docutils literal notranslate"><span class="pre">Ioo</span>  <span class="pre">(x₀</span> <span class="pre">-</span> <span class="pre">ε)</span> <span class="pre">(x₀</span> <span class="pre">+</span> <span class="pre">ε)</span></code> form a basis for the neighborhood topology on <code class="docutils literal notranslate"><span class="pre">ℝ</span></code> is stated as follows:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">x₀</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">HasBasis</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">x₀</span><span class="o">)</span> <span class="o">(</span><span class="k">fun</span> <span class="n">ε</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">↦</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">ε</span><span class="o">)</span> <span class="k">fun</span> <span class="n">ε</span> <span class="bp">↦</span> <span class="n">Ioo</span> <span class="o">(</span><span class="n">x₀</span> <span class="bp">-</span> <span class="n">ε</span><span class="o">)</span> <span class="o">(</span><span class="n">x₀</span> <span class="bp">+</span> <span class="n">ε</span><span class="o">)</span> <span class="o">:=</span> <span class="n">nhds_basis_Ioo_pos</span> <span class="n">x₀</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">HasBasis</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">x₀</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="o">)</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">Ioo</span><span class="w"> </span><span class="o">(</span><span class="n">x₀</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">ε</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">x₀</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">ε</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">nhds_basis_Ioo_pos</span><span class="w"> </span><span class="n">x₀</span> </pre></div> </div> <p>There is also a nice basis for the filter <code class="docutils literal notranslate"><span class="pre">atTop</span></code>. The lemma
-
@@ -419,11 +420,11 @@ us to reformulate a statement of the form <code class="docutils literal notranslate"><span class="pre">Tendsto</span> <span class="pre">f</span> <span class="pre">F</span> <span class="pre">G</span></code>given bases for <code class="docutils literal notranslate"><span class="pre">F</span></code> and <code class="docutils literal notranslate"><span class="pre">G</span></code>. Putting these pieces together gives us essentially the notion of convergence that we used in <a class="reference internal" href="C03_Logic.html#sequences-and-convergence"><span class="std std-numref">Section 3.6</span></a>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">u</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">x₀</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">Tendsto</span> <span class="n">u</span> <span class="n">atTop</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">x₀</span><span class="o">)</span> <span class="bp">↔</span> <span class="bp">∀</span> <span class="n">ε</span> <span class="bp">></span> <span class="mi">0</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">N</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">n</span> <span class="bp">≥</span> <span class="n">N</span><span class="o">,</span> <span class="n">u</span> <span class="n">n</span> <span class="bp">∈</span> <span class="n">Ioo</span> <span class="o">(</span><span class="n">x₀</span> <span class="bp">-</span> <span class="n">ε</span><span class="o">)</span> <span class="o">(</span><span class="n">x₀</span> <span class="bp">+</span> <span class="n">ε</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="k">have</span> <span class="o">:</span> <span class="n">atTop.HasBasis</span> <span class="o">(</span><span class="k">fun</span> <span class="n">_</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">↦</span> <span class="n">True</span><span class="o">)</span> <span class="n">Ici</span> <span class="o">:=</span> <span class="n">atTop_basis</span> <span class="n">rw</span> <span class="o">[</span><span class="n">this.tendsto_iff</span> <span class="o">(</span><span class="n">nhds_basis_Ioo_pos</span> <span class="n">x₀</span><span class="o">)]</span> <span class="n">simp</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">x₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">atTop</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">x₀</span><span class="o">)</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">Ioo</span><span class="w"> </span><span class="o">(</span><span class="n">x₀</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">ε</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">x₀</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">ε</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">atTop.HasBasis</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">True</span><span class="o">)</span><span class="w"> </span><span class="n">Ici</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">atTop_basis</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">this.tendsto_iff</span><span class="w"> </span><span class="o">(</span><span class="n">nhds_basis_Ioo_pos</span><span class="w"> </span><span class="n">x₀</span><span class="o">)]</span> <span class="w"> </span><span class="n">simp</span> </pre></div> </div> <p>We now show how filters facilitate working with properties that hold for sufficiently large numbers
-
@@ -443,9 +444,9 @@ but we can use the more suggestive notation <code class="docutils literal notranslate"><span class="pre">∀ᶠ</span> <span class="pre">n</span> <span class="pre">in</span> <span class="pre">atTop,</span> <span class="pre">P</span> <span class="pre">n</span></code>.Here the superscripted <code class="docutils literal notranslate"><span class="pre">f</span></code> stands for “Filter.” You can think of the notation as saying that for all <code class="docutils literal notranslate"><span class="pre">n</span></code> in the “set of very large numbers,” <code class="docutils literal notranslate"><span class="pre">P</span> <span class="pre">n</span></code> holds. The <code class="docutils literal notranslate"><span class="pre">∀ᶠ</span></code> notation stands for <code class="docutils literal notranslate"><span class="pre">Filter.Eventually</span></code>, and the lemma <code class="docutils literal notranslate"><span class="pre">Filter.Eventually.and</span></code> uses the intersection property of filters to do what we just described:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">P</span> <span class="n">Q</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="kt">Prop</span><span class="o">)</span> <span class="o">(</span><span class="n">hP</span> <span class="o">:</span> <span class="bp">∀ᶠ</span> <span class="n">n</span> <span class="k">in</span> <span class="n">atTop</span><span class="o">,</span> <span class="n">P</span> <span class="n">n</span><span class="o">)</span> <span class="o">(</span><span class="n">hQ</span> <span class="o">:</span> <span class="bp">∀ᶠ</span> <span class="n">n</span> <span class="k">in</span> <span class="n">atTop</span><span class="o">,</span> <span class="n">Q</span> <span class="n">n</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∀ᶠ</span> <span class="n">n</span> <span class="k">in</span> <span class="n">atTop</span><span class="o">,</span> <span class="n">P</span> <span class="n">n</span> <span class="bp">∧</span> <span class="n">Q</span> <span class="n">n</span> <span class="o">:=</span> <span class="n">hP.and</span> <span class="n">hQ</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">P</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="kt">Prop</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hP</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">atTop</span><span class="o">,</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hQ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">atTop</span><span class="o">,</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">atTop</span><span class="o">,</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">hP.and</span><span class="w"> </span><span class="n">hQ</span> </pre></div> </div> <p>This notation is so convenient and intuitive that we also have specializations
-
@@ -456,13 +457,13 @@ <code class="docutils literal notranslate"><span class="pre">u</span></code> tends to <code class="docutils literal notranslate"><span class="pre">x₀</span></code> if and only if <code class="docutils literal notranslate"><span class="pre">v</span></code> tends to <code class="docutils literal notranslate"><span class="pre">x₀</span></code>.First we’ll use the generic <code class="docutils literal notranslate"><span class="pre">Eventually</span></code> and then the one specialized for the equality predicate, <code class="docutils literal notranslate"><span class="pre">EventuallyEq</span></code>. The two statements are definitionally equivalent so the same proof work in both cases.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">u</span> <span class="n">v</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">∀ᶠ</span> <span class="n">n</span> <span class="k">in</span> <span class="n">atTop</span><span class="o">,</span> <span class="n">u</span> <span class="n">n</span> <span class="bp">=</span> <span class="n">v</span> <span class="n">n</span><span class="o">)</span> <span class="o">(</span><span class="n">x₀</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">Tendsto</span> <span class="n">u</span> <span class="n">atTop</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">x₀</span><span class="o">)</span> <span class="bp">↔</span> <span class="n">Tendsto</span> <span class="n">v</span> <span class="n">atTop</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">x₀</span><span class="o">)</span> <span class="o">:=</span> <span class="n">tendsto_congr'</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">atTop</span><span class="o">,</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">x₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">atTop</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">x₀</span><span class="o">)</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="n">atTop</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">x₀</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">tendsto_congr'</span><span class="w"> </span><span class="n">h</span> <span class="kd">example</span> <span class="o">(</span><span class="n">u</span> <span class="n">v</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">u</span> <span class="bp">=ᶠ</span><span class="o">[</span><span class="n">atTop</span><span class="o">]</span> <span class="n">v</span><span class="o">)</span> <span class="o">(</span><span class="n">x₀</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">Tendsto</span> <span class="n">u</span> <span class="n">atTop</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">x₀</span><span class="o">)</span> <span class="bp">↔</span> <span class="n">Tendsto</span> <span class="n">v</span> <span class="n">atTop</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">x₀</span><span class="o">)</span> <span class="o">:=</span> <span class="n">tendsto_congr'</span> <span class="n">h</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">=ᶠ</span><span class="o">[</span><span class="n">atTop</span><span class="o">]</span><span class="w"> </span><span class="n">v</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">x₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">atTop</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">x₀</span><span class="o">)</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="n">atTop</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">x₀</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">tendsto_congr'</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>It is instructive to review the definition of filters in terms of <code class="docutils literal notranslate"><span class="pre">Eventually</span></code>.
-
@@ -472,25 +473,25 @@ <li><p>the condition <code class="docutils literal notranslate"><span class="pre">univ</span> <span class="pre">∈</span> <span class="pre">F</span></code> ensures <code class="docutils literal notranslate"><span class="pre">(∀</span> <span class="pre">x,</span> <span class="pre">P</span> <span class="pre">x)</span> <span class="pre">→</span> <span class="pre">∀ᶠ</span> <span class="pre">x</span> <span class="pre">in</span> <span class="pre">F,</span> <span class="pre">P</span> <span class="pre">x</span></code>,</p></li><li><p>the condition <code class="docutils literal notranslate"><span class="pre">U</span> <span class="pre">∈</span> <span class="pre">F</span> <span class="pre">→</span> <span class="pre">U</span> <span class="pre">⊆</span> <span class="pre">V</span> <span class="pre">→</span> <span class="pre">V</span> <span class="pre">∈</span> <span class="pre">F</span></code> ensures <code class="docutils literal notranslate"><span class="pre">(∀ᶠ</span> <span class="pre">x</span> <span class="pre">in</span> <span class="pre">F,</span> <span class="pre">P</span> <span class="pre">x)</span> <span class="pre">→</span> <span class="pre">(∀</span> <span class="pre">x,</span> <span class="pre">P</span> <span class="pre">x</span> <span class="pre">→</span> <span class="pre">Q</span> <span class="pre">x)</span> <span class="pre">→</span> <span class="pre">∀ᶠ</span> <span class="pre">x</span> <span class="pre">in</span> <span class="pre">F,</span> <span class="pre">Q</span> <span class="pre">x</span></code>, and</p></li> <li><p>the condition <code class="docutils literal notranslate"><span class="pre">U</span> <span class="pre">∈</span> <span class="pre">F</span> <span class="pre">→</span> <span class="pre">V</span> <span class="pre">∈</span> <span class="pre">F</span> <span class="pre">→</span> <span class="pre">U</span> <span class="pre">∩</span> <span class="pre">V</span> <span class="pre">∈</span> <span class="pre">F</span></code> ensures <code class="docutils literal notranslate"><span class="pre">(∀ᶠ</span> <span class="pre">x</span> <span class="pre">in</span> <span class="pre">F,</span> <span class="pre">P</span> <span class="pre">x)</span> <span class="pre">→</span> <span class="pre">(∀ᶠ</span> <span class="pre">x</span> <span class="pre">in</span> <span class="pre">F,</span> <span class="pre">Q</span> <span class="pre">x)</span> <span class="pre">→</span> <span class="pre">∀ᶠ</span> <span class="pre">x</span> <span class="pre">in</span> <span class="pre">F,</span> <span class="pre">P</span> <span class="pre">x</span> <span class="pre">∧</span> <span class="pre">Q</span> <span class="pre">x</span></code>.</p></li> </ul> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="n">Eventually.of_forall</span> <span class="k">#check</span> <span class="n">Eventually.mono</span> <span class="k">#check</span> <span class="n">Eventually.and</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="n">Eventually.of_forall</span> <span class="k">#check</span><span class="w"> </span><span class="n">Eventually.mono</span> <span class="k">#check</span><span class="w"> </span><span class="n">Eventually.and</span> </pre></div> </div> <p>The second item, corresponding to <code class="docutils literal notranslate"><span class="pre">Eventually.mono</span></code>, supports nice ways of using filters, especially when combined with <code class="docutils literal notranslate"><span class="pre">Eventually.and</span></code>. The <code class="docutils literal notranslate"><span class="pre">filter_upwards</span></code> tactic allows us to combine them. Compare:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">P</span> <span class="n">Q</span> <span class="n">R</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="kt">Prop</span><span class="o">)</span> <span class="o">(</span><span class="n">hP</span> <span class="o">:</span> <span class="bp">∀ᶠ</span> <span class="n">n</span> <span class="k">in</span> <span class="n">atTop</span><span class="o">,</span> <span class="n">P</span> <span class="n">n</span><span class="o">)</span> <span class="o">(</span><span class="n">hQ</span> <span class="o">:</span> <span class="bp">∀ᶠ</span> <span class="n">n</span> <span class="k">in</span> <span class="n">atTop</span><span class="o">,</span> <span class="n">Q</span> <span class="n">n</span><span class="o">)</span> <span class="o">(</span><span class="n">hR</span> <span class="o">:</span> <span class="bp">∀ᶠ</span> <span class="n">n</span> <span class="k">in</span> <span class="n">atTop</span><span class="o">,</span> <span class="n">P</span> <span class="n">n</span> <span class="bp">∧</span> <span class="n">Q</span> <span class="n">n</span> <span class="bp">→</span> <span class="n">R</span> <span class="n">n</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∀ᶠ</span> <span class="n">n</span> <span class="k">in</span> <span class="n">atTop</span><span class="o">,</span> <span class="n">R</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="o">(</span><span class="n">hP.and</span> <span class="o">(</span><span class="n">hQ.and</span> <span class="n">hR</span><span class="o">))</span><span class="bp">.</span><span class="n">mono</span> <span class="n">rintro</span> <span class="n">n</span> <span class="o">⟨</span><span class="n">h</span><span class="o">,</span> <span class="n">h'</span><span class="o">,</span> <span class="n">h''</span><span class="o">⟩</span> <span class="n">exact</span> <span class="n">h''</span> <span class="o">⟨</span><span class="n">h</span><span class="o">,</span> <span class="n">h'</span><span class="o">⟩</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">P</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="kt">Prop</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hP</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">atTop</span><span class="o">,</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hQ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">atTop</span><span class="o">,</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="n">n</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="n">hR</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">atTop</span><span class="o">,</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">atTop</span><span class="o">,</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="o">(</span><span class="n">hP.and</span><span class="w"> </span><span class="o">(</span><span class="n">hQ.and</span><span class="w"> </span><span class="n">hR</span><span class="o">))</span><span class="bp">.</span><span class="n">mono</span> <span class="w"> </span><span class="n">rintro</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">⟨</span><span class="n">h</span><span class="o">,</span><span class="w"> </span><span class="n">h'</span><span class="o">,</span><span class="w"> </span><span class="n">h''</span><span class="o">⟩</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h''</span><span class="w"> </span><span class="o">⟨</span><span class="n">h</span><span class="o">,</span><span class="w"> </span><span class="n">h'</span><span class="o">⟩</span> <span class="kd">example</span> <span class="o">(</span><span class="n">P</span> <span class="n">Q</span> <span class="n">R</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="kt">Prop</span><span class="o">)</span> <span class="o">(</span><span class="n">hP</span> <span class="o">:</span> <span class="bp">∀ᶠ</span> <span class="n">n</span> <span class="k">in</span> <span class="n">atTop</span><span class="o">,</span> <span class="n">P</span> <span class="n">n</span><span class="o">)</span> <span class="o">(</span><span class="n">hQ</span> <span class="o">:</span> <span class="bp">∀ᶠ</span> <span class="n">n</span> <span class="k">in</span> <span class="n">atTop</span><span class="o">,</span> <span class="n">Q</span> <span class="n">n</span><span class="o">)</span> <span class="o">(</span><span class="n">hR</span> <span class="o">:</span> <span class="bp">∀ᶠ</span> <span class="n">n</span> <span class="k">in</span> <span class="n">atTop</span><span class="o">,</span> <span class="n">P</span> <span class="n">n</span> <span class="bp">∧</span> <span class="n">Q</span> <span class="n">n</span> <span class="bp">→</span> <span class="n">R</span> <span class="n">n</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∀ᶠ</span> <span class="n">n</span> <span class="k">in</span> <span class="n">atTop</span><span class="o">,</span> <span class="n">R</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">filter_upwards</span> <span class="o">[</span><span class="n">hP</span><span class="o">,</span> <span class="n">hQ</span><span class="o">,</span> <span class="n">hR</span><span class="o">]</span> <span class="k">with</span> <span class="n">n</span> <span class="n">h</span> <span class="n">h'</span> <span class="n">h''</span> <span class="n">exact</span> <span class="n">h''</span> <span class="o">⟨</span><span class="n">h</span><span class="o">,</span> <span class="n">h'</span><span class="o">⟩</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">P</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="kt">Prop</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hP</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">atTop</span><span class="o">,</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hQ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">atTop</span><span class="o">,</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="n">n</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="n">hR</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">atTop</span><span class="o">,</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">Q</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">atTop</span><span class="o">,</span><span class="w"> </span><span class="n">R</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">filter_upwards</span><span class="w"> </span><span class="o">[</span><span class="n">hP</span><span class="o">,</span><span class="w"> </span><span class="n">hQ</span><span class="o">,</span><span class="w"> </span><span class="n">hR</span><span class="o">]</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="n">h'</span><span class="w"> </span><span class="n">h''</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">h''</span><span class="w"> </span><span class="o">⟨</span><span class="n">h</span><span class="o">,</span><span class="w"> </span><span class="n">h'</span><span class="o">⟩</span> </pre></div> </div> <p>Readers who know about measure theory will note that the filter <code class="docutils literal notranslate"><span class="pre">μ.ae</span></code> of sets whose complement has measure zero
-
@@ -515,13 +516,13 @@ topology library.See if you can prove it using the quoted lemmas, using the fact that <code class="docutils literal notranslate"><span class="pre">ClusterPt</span> <span class="pre">x</span> <span class="pre">F</span></code> means <code class="docutils literal notranslate"><span class="pre">(𝓝</span> <span class="pre">x</span> <span class="pre">⊓</span> <span class="pre">F).NeBot</span></code> and that, by definition, the assumption <code class="docutils literal notranslate"><span class="pre">∀ᶠ</span> <span class="pre">n</span> <span class="pre">in</span> <span class="pre">atTop,</span> <span class="pre">u</span> <span class="pre">n</span> <span class="pre">∈</span> <span class="pre">M</span></code> means <code class="docutils literal notranslate"><span class="pre">M</span> <span class="pre">∈</span> <span class="pre">map</span> <span class="pre">u</span> <span class="pre">atTop</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span> <span class="n">mem_closure_iff_clusterPt</span> <span class="k">#check</span> <span class="n">le_principal_iff</span> <span class="k">#check</span> <span class="n">neBot_of_le</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="k">#check</span><span class="w"> </span><span class="n">mem_closure_iff_clusterPt</span> <span class="k">#check</span><span class="w"> </span><span class="n">le_principal_iff</span> <span class="k">#check</span><span class="w"> </span><span class="n">neBot_of_le</span> <span class="kd">example</span> <span class="o">(</span><span class="n">u</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">M</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">hux</span> <span class="o">:</span> <span class="n">Tendsto</span> <span class="n">u</span> <span class="n">atTop</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">x</span><span class="o">))</span> <span class="o">(</span><span class="n">huM</span> <span class="o">:</span> <span class="bp">∀ᶠ</span> <span class="n">n</span> <span class="k">in</span> <span class="n">atTop</span><span class="o">,</span> <span class="n">u</span> <span class="n">n</span> <span class="bp">∈</span> <span class="n">M</span><span class="o">)</span> <span class="o">:</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">closure</span> <span class="n">M</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">M</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hux</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">atTop</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">x</span><span class="o">))</span> <span class="w"> </span><span class="o">(</span><span class="n">huM</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">atTop</span><span class="o">,</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">closure</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> </section>
-
@@ -531,13 +532,13 @@ <p>Examples in the previous section focus on sequences of real numbers. In this section we will go up a bit in generality and focus onmetric spaces. A metric space is a type <code class="docutils literal notranslate"><span class="pre">X</span></code> equipped with a distance function <code class="docutils literal notranslate"><span class="pre">dist</span> <span class="pre">:</span> <span class="pre">X</span> <span class="pre">→</span> <span class="pre">X</span> <span class="pre">→</span> <span class="pre">ℝ</span></code> which is a generalization of the function <code class="docutils literal notranslate"><span class="pre">fun</span> <span class="pre">x</span> <span class="pre">y</span> <span class="pre">↦</span> <span class="pre">|x</span> <span class="pre">-</span> <span class="pre">y|</span></code> from the case where <code class="docutils literal notranslate"><span class="pre">X</span> <span class="pre">=</span> <span class="pre">ℝ</span></code>.</p> <p>Introducing such a space is easy and we will check all properties required from the distance function.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">X</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">MetricSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">X</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">X</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">MetricSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">dist</span> <span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">dist_nonneg</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">dist</span> <span class="n">a</span> <span class="n">b</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">dist_eq_zero</span> <span class="o">:</span> <span class="n">dist</span> <span class="n">a</span> <span class="n">b</span> <span class="bp">=</span> <span class="mi">0</span> <span class="bp">↔</span> <span class="n">a</span> <span class="bp">=</span> <span class="n">b</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">dist_comm</span> <span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">dist</span> <span class="n">a</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">dist</span> <span class="n">b</span> <span class="n">a</span><span class="o">)</span> <span class="k">#check</span> <span class="o">(</span><span class="n">dist_triangle</span> <span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">:</span> <span class="n">dist</span> <span class="n">a</span> <span class="n">c</span> <span class="bp">≤</span> <span class="n">dist</span> <span class="n">a</span> <span class="n">b</span> <span class="bp">+</span> <span class="n">dist</span> <span class="n">b</span> <span class="n">c</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">dist</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">dist_nonneg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">dist_eq_zero</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">dist_comm</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">a</span><span class="o">)</span> <span class="k">#check</span><span class="w"> </span><span class="o">(</span><span class="n">dist_triangle</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">c</span><span class="o">)</span> </pre></div> </div> <p>Note we also have variants where the distance can be infinite or where <code class="docutils literal notranslate"><span class="pre">dist</span> <span class="pre">a</span> <span class="pre">b</span></code> can be zero without having <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">=</span> <span class="pre">b</span></code> or both.
-
@@ -549,14 +550,14 @@ <h3><span class="section-number">10.2.1. </span>Convergence and continuity<a class="headerlink" href="#convergence-and-continuity" title="Link to this heading"></a></h3><p>Using distance functions, we can already define convergent sequences and continuous functions between metric spaces. They are actually defined in a more general setting covered in the next section, but we have lemmas recasting the definition in terms of distances.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">u</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">X</span><span class="o">}</span> <span class="o">{</span><span class="n">a</span> <span class="o">:</span> <span class="n">X</span><span class="o">}</span> <span class="o">:</span> <span class="n">Tendsto</span> <span class="n">u</span> <span class="n">atTop</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">a</span><span class="o">)</span> <span class="bp">↔</span> <span class="bp">∀</span> <span class="n">ε</span> <span class="bp">></span> <span class="mi">0</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">N</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">n</span> <span class="bp">≥</span> <span class="n">N</span><span class="o">,</span> <span class="n">dist</span> <span class="o">(</span><span class="n">u</span> <span class="n">n</span><span class="o">)</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">ε</span> <span class="o">:=</span> <span class="n">Metric.tendsto_atTop</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">u</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">atTop</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Metric.tendsto_atTop</span> <span class="kd">example</span> <span class="o">{</span><span class="n">X</span> <span class="n">Y</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">MetricSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">[</span><span class="n">MetricSpace</span> <span class="n">Y</span><span class="o">]</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">}</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="n">f</span> <span class="bp">↔</span> <span class="bp">∀</span> <span class="n">x</span> <span class="o">:</span> <span class="n">X</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">ε</span> <span class="bp">></span> <span class="mi">0</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">δ</span> <span class="bp">></span> <span class="mi">0</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">x'</span><span class="o">,</span> <span class="n">dist</span> <span class="n">x'</span> <span class="n">x</span> <span class="bp"><</span> <span class="n">δ</span> <span class="bp">→</span> <span class="n">dist</span> <span class="o">(</span><span class="n">f</span> <span class="n">x'</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="n">x</span><span class="o">)</span> <span class="bp"><</span> <span class="n">ε</span> <span class="o">:=</span> <span class="n">Metric.continuous_iff</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">X</span><span class="w"> </span><span class="n">Y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">MetricSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">MetricSpace</span><span class="w"> </span><span class="n">Y</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">}</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">↔</span> <span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">δ</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x'</span><span class="o">,</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="n">x'</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">δ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">x'</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Metric.continuous_iff</span> </pre></div> </div> <p id="index-3">A <em>lot</em> of lemmas have some continuity assumptions, so we end up proving a lot of continuity results and there
-
@@ -564,8 +565,8 @@ is a <code class="docutils literal notranslate"><span class="pre">continuity</span></code> tactic devoted to this task. Let’s prove a continuity statement that will be neededin an exercise below. Notice that Lean knows how to treat a product of two metric spaces as a metric space, so it makes sense to consider continuous functions from <code class="docutils literal notranslate"><span class="pre">X</span> <span class="pre">×</span> <span class="pre">X</span></code> to <code class="docutils literal notranslate"><span class="pre">ℝ</span></code>. In particular the (uncurried version of the) distance function is such a function.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">X</span> <span class="n">Y</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">MetricSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">[</span><span class="n">MetricSpace</span> <span class="n">Y</span><span class="o">]</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">}</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="k">fun</span> <span class="n">p</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">×</span> <span class="n">X</span> <span class="bp">↦</span> <span class="n">dist</span> <span class="o">(</span><span class="n">f</span> <span class="n">p.1</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="n">p.2</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">continuity</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">X</span><span class="w"> </span><span class="n">Y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">MetricSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">MetricSpace</span><span class="w"> </span><span class="n">Y</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">p</span><span class="bp">.</span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">p</span><span class="bp">.</span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">continuity</span> </pre></div> </div> <p>This tactic is a bit slow, so it is also useful to know
-
@@ -579,9 +580,9 @@ We can do the same for the second component to get continuity of <code class="docutils literal notranslate"><span class="pre">fun</span> <span class="pre">p</span> <span class="pre">:</span> <span class="pre">X</span> <span class="pre">×</span> <span class="pre">X</span> <span class="pre">↦</span> <span class="pre">f</span> <span class="pre">p.2</span></code>. We then assemblethose two continuities using <code class="docutils literal notranslate"><span class="pre">Continuous.prod_mk</span></code> to get <code class="docutils literal notranslate"><span class="pre">(hf.comp</span> <span class="pre">continuous_fst).prod_mk</span> <span class="pre">(hf.comp</span> <span class="pre">continuous_snd)</span> <span class="pre">:</span> <span class="pre">Continuous</span> <span class="pre">(fun</span> <span class="pre">p</span> <span class="pre">:</span> <span class="pre">X</span> <span class="pre">×</span> <span class="pre">X</span> <span class="pre">↦</span> <span class="pre">(f</span> <span class="pre">p.1,</span> <span class="pre">f</span> <span class="pre">p.2))</span></code> and compose once more to get our full proof.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">X</span> <span class="n">Y</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">MetricSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">[</span><span class="n">MetricSpace</span> <span class="n">Y</span><span class="o">]</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">}</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="k">fun</span> <span class="n">p</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">×</span> <span class="n">X</span> <span class="bp">↦</span> <span class="n">dist</span> <span class="o">(</span><span class="n">f</span> <span class="n">p.1</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="n">p.2</span><span class="o">)</span> <span class="o">:=</span> <span class="n">continuous_dist.comp</span> <span class="o">((</span><span class="n">hf.comp</span> <span class="n">continuous_fst</span><span class="o">)</span><span class="bp">.</span><span class="n">prod_mk</span> <span class="o">(</span><span class="n">hf.comp</span> <span class="n">continuous_snd</span><span class="o">))</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">X</span><span class="w"> </span><span class="n">Y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">MetricSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">MetricSpace</span><span class="w"> </span><span class="n">Y</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">p</span><span class="bp">.</span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">p</span><span class="bp">.</span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">continuous_dist.comp</span><span class="w"> </span><span class="o">((</span><span class="n">hf.comp</span><span class="w"> </span><span class="n">continuous_fst</span><span class="o">)</span><span class="bp">.</span><span class="n">prod_mk</span><span class="w"> </span><span class="o">(</span><span class="n">hf.comp</span><span class="w"> </span><span class="n">continuous_snd</span><span class="o">))</span> </pre></div> </div> <p>The combination of <code class="docutils literal notranslate"><span class="pre">Continuous.prod_mk</span></code> and <code class="docutils literal notranslate"><span class="pre">continuous_dist</span></code> via <code class="docutils literal notranslate"><span class="pre">Continuous.comp</span></code> feels clunky,
-
@@ -597,15 +598,15 @@ <p>A better lemma to apply here is<code class="docutils literal notranslate"><span class="pre">Continuous.dist</span> <span class="pre">{f</span> <span class="pre">g</span> <span class="pre">:</span> <span class="pre">X</span> <span class="pre">→</span> <span class="pre">Y}</span> <span class="pre">:</span> <span class="pre">Continuous</span> <span class="pre">f</span> <span class="pre">→</span> <span class="pre">Continuous</span> <span class="pre">g</span> <span class="pre">→</span> <span class="pre">Continuous</span> <span class="pre">(fun</span> <span class="pre">x</span> <span class="pre">↦</span> <span class="pre">dist</span> <span class="pre">(f</span> <span class="pre">x)</span> <span class="pre">(g</span> <span class="pre">x))</span></code> which is nicer to Lean’s elaborator and also provides a shorter proof when directly providing a full proof term, as can be seen from the following two new proofs of the above statement:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">X</span> <span class="n">Y</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">MetricSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">[</span><span class="n">MetricSpace</span> <span class="n">Y</span><span class="o">]</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">}</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="k">fun</span> <span class="n">p</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">×</span> <span class="n">X</span> <span class="bp">↦</span> <span class="n">dist</span> <span class="o">(</span><span class="n">f</span> <span class="n">p.1</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="n">p.2</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">apply</span> <span class="n">Continuous.dist</span> <span class="n">exact</span> <span class="n">hf.comp</span> <span class="n">continuous_fst</span> <span class="n">exact</span> <span class="n">hf.comp</span> <span class="n">continuous_snd</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">X</span><span class="w"> </span><span class="n">Y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">MetricSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">MetricSpace</span><span class="w"> </span><span class="n">Y</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">p</span><span class="bp">.</span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">p</span><span class="bp">.</span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">apply</span><span class="w"> </span><span class="n">Continuous.dist</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">hf.comp</span><span class="w"> </span><span class="n">continuous_fst</span> <span class="w"> </span><span class="n">exact</span><span class="w"> </span><span class="n">hf.comp</span><span class="w"> </span><span class="n">continuous_snd</span> <span class="kd">example</span> <span class="o">{</span><span class="n">X</span> <span class="n">Y</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">MetricSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">[</span><span class="n">MetricSpace</span> <span class="n">Y</span><span class="o">]</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">}</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="k">fun</span> <span class="n">p</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">×</span> <span class="n">X</span> <span class="bp">↦</span> <span class="n">dist</span> <span class="o">(</span><span class="n">f</span> <span class="n">p.1</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="n">p.2</span><span class="o">)</span> <span class="o">:=</span> <span class="o">(</span><span class="n">hf.comp</span> <span class="n">continuous_fst</span><span class="o">)</span><span class="bp">.</span><span class="n">dist</span> <span class="o">(</span><span class="n">hf.comp</span> <span class="n">continuous_snd</span><span class="o">)</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">X</span><span class="w"> </span><span class="n">Y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">MetricSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">MetricSpace</span><span class="w"> </span><span class="n">Y</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">p</span><span class="bp">.</span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">p</span><span class="bp">.</span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">(</span><span class="n">hf.comp</span><span class="w"> </span><span class="n">continuous_fst</span><span class="o">)</span><span class="bp">.</span><span class="n">dist</span><span class="w"> </span><span class="o">(</span><span class="n">hf.comp</span><span class="w"> </span><span class="n">continuous_snd</span><span class="o">)</span> </pre></div> </div> <p>Note that, without the elaboration issue coming from composition, another way to compress
-
@@ -615,66 +616,66 @@ <p>Since it is sad to decide between a version which is better for elaboration and a version which is shorterto type, let us wrap this discussion with a last bit of compression offered by <code class="docutils literal notranslate"><span class="pre">Continuous.fst'</span></code> which allows to compress <code class="docutils literal notranslate"><span class="pre">hf.comp</span> <span class="pre">continuous_fst</span></code> to <code class="docutils literal notranslate"><span class="pre">hf.fst'</span></code> (and the same with <code class="docutils literal notranslate"><span class="pre">snd</span></code>) and get our final proof, now bordering obfuscation.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">X</span> <span class="n">Y</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">MetricSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">[</span><span class="n">MetricSpace</span> <span class="n">Y</span><span class="o">]</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">}</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="k">fun</span> <span class="n">p</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">×</span> <span class="n">X</span> <span class="bp">↦</span> <span class="n">dist</span> <span class="o">(</span><span class="n">f</span> <span class="n">p.1</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="n">p.2</span><span class="o">)</span> <span class="o">:=</span> <span class="n">hf.fst'.dist</span> <span class="n">hf.snd'</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">X</span><span class="w"> </span><span class="n">Y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">MetricSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">MetricSpace</span><span class="w"> </span><span class="n">Y</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">p</span><span class="bp">.</span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">p</span><span class="bp">.</span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">hf.fst'.dist</span><span class="w"> </span><span class="n">hf.snd'</span> </pre></div> </div> <p>It’s your turn now to prove some continuity lemma. After trying the continuity tactic, you will need <code class="docutils literal notranslate"><span class="pre">Continuous.add</span></code>, <code class="docutils literal notranslate"><span class="pre">continuous_pow</span></code> and <code class="docutils literal notranslate"><span class="pre">continuous_id</span></code> to do it by hand.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">X</span><span class="o">}</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="k">fun</span> <span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">↦</span> <span class="n">f</span> <span class="o">(</span><span class="n">x</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">+</span> <span class="n">x</span><span class="o">)</span> <span class="o">:=</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>So far we saw continuity as a global notion, but one can also define continuity at a point.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">X</span> <span class="n">Y</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">MetricSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">[</span><span class="n">MetricSpace</span> <span class="n">Y</span><span class="o">]</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">X</span><span class="o">)</span> <span class="o">:</span> <span class="n">ContinuousAt</span> <span class="n">f</span> <span class="n">a</span> <span class="bp">↔</span> <span class="bp">∀</span> <span class="n">ε</span> <span class="bp">></span> <span class="mi">0</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">δ</span> <span class="bp">></span> <span class="mi">0</span><span class="o">,</span> <span class="bp">∀</span> <span class="o">{</span><span class="n">x</span><span class="o">},</span> <span class="n">dist</span> <span class="n">x</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">δ</span> <span class="bp">→</span> <span class="n">dist</span> <span class="o">(</span><span class="n">f</span> <span class="n">x</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="n">a</span><span class="o">)</span> <span class="bp"><</span> <span class="n">ε</span> <span class="o">:=</span> <span class="n">Metric.continuousAt_iff</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">X</span><span class="w"> </span><span class="n">Y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">MetricSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">MetricSpace</span><span class="w"> </span><span class="n">Y</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">ContinuousAt</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">δ</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="o">},</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">δ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Metric.continuousAt_iff</span> </pre></div> </div> </section> <section id="balls-open-sets-and-closed-sets"> <h3><span class="section-number">10.2.2. </span>Balls, open sets and closed sets<a class="headerlink" href="#balls-open-sets-and-closed-sets" title="Link to this heading"></a></h3> <p>Once we have a distance function, the most important geometric definitions are (open) balls and closed balls.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">(</span><span class="n">r</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">Metric.ball</span> <span class="n">a</span> <span class="n">r</span> <span class="bp">=</span> <span class="o">{</span> <span class="n">b</span> <span class="bp">|</span> <span class="n">dist</span> <span class="n">b</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">r</span> <span class="o">}</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Metric.ball</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="o">}</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">Metric.closedBall</span> <span class="n">a</span> <span class="n">r</span> <span class="bp">=</span> <span class="o">{</span> <span class="n">b</span> <span class="bp">|</span> <span class="n">dist</span> <span class="n">b</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">r</span> <span class="o">}</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Metric.closedBall</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="o">}</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> </pre></div> </div> <p>Note that <cite>r</cite> is any real number here, there is no sign restriction. Of course some statements do require a radius condition.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">hr</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">r</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">∈</span> <span class="n">Metric.ball</span> <span class="n">a</span> <span class="n">r</span> <span class="o">:=</span> <span class="n">Metric.mem_ball_self</span> <span class="n">hr</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">hr</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">r</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">Metric.ball</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Metric.mem_ball_self</span><span class="w"> </span><span class="n">hr</span> <span class="kd">example</span> <span class="o">(</span><span class="n">hr</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">r</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">∈</span> <span class="n">Metric.closedBall</span> <span class="n">a</span> <span class="n">r</span> <span class="o">:=</span> <span class="n">Metric.mem_closedBall_self</span> <span class="n">hr</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">hr</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">r</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">Metric.closedBall</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Metric.mem_closedBall_self</span><span class="w"> </span><span class="n">hr</span> </pre></div> </div> <p>Once we have balls, we can define open sets. They are actually defined in a more general setting covered in the next section, but we have lemmas recasting the definition in terms of balls.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span><span class="o">)</span> <span class="o">:</span> <span class="n">IsOpen</span> <span class="n">s</span> <span class="bp">↔</span> <span class="bp">∀</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">ε</span> <span class="bp">></span> <span class="mi">0</span><span class="o">,</span> <span class="n">Metric.ball</span> <span class="n">x</span> <span class="n">ε</span> <span class="bp">⊆</span> <span class="n">s</span> <span class="o">:=</span> <span class="n">Metric.isOpen_iff</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsOpen</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="n">Metric.ball</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Metric.isOpen_iff</span> </pre></div> </div> <p>Then closed sets are sets whose complement is open. Their important property is they are closed under limits. The closure of a set is the smallest closed set containing it.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span><span class="o">}</span> <span class="o">:</span> <span class="n">IsClosed</span> <span class="n">s</span> <span class="bp">↔</span> <span class="n">IsOpen</span> <span class="o">(</span><span class="n">s</span><span class="bp">ᶜ</span><span class="o">)</span> <span class="o">:=</span> <span class="n">isOpen_compl_iff.symm</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsClosed</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">IsOpen</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="bp">ᶜ</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">isOpen_compl_iff.symm</span> <span class="kd">example</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span><span class="o">}</span> <span class="o">(</span><span class="n">hs</span> <span class="o">:</span> <span class="n">IsClosed</span> <span class="n">s</span><span class="o">)</span> <span class="o">{</span><span class="n">u</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">X</span><span class="o">}</span> <span class="o">(</span><span class="n">hu</span> <span class="o">:</span> <span class="n">Tendsto</span> <span class="n">u</span> <span class="n">atTop</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">a</span><span class="o">))</span> <span class="o">(</span><span class="n">hus</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">n</span><span class="o">,</span> <span class="n">u</span> <span class="n">n</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">∈</span> <span class="n">s</span> <span class="o">:=</span> <span class="n">hs.mem_of_tendsto</span> <span class="n">hu</span> <span class="o">(</span><span class="n">Eventually.of_forall</span> <span class="n">hus</span><span class="o">)</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsClosed</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">u</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hu</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">atTop</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">a</span><span class="o">))</span> <span class="w"> </span><span class="o">(</span><span class="n">hus</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">hs.mem_of_tendsto</span><span class="w"> </span><span class="n">hu</span><span class="w"> </span><span class="o">(</span><span class="n">Eventually.of_forall</span><span class="w"> </span><span class="n">hus</span><span class="o">)</span> <span class="kd">example</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span><span class="o">}</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">∈</span> <span class="n">closure</span> <span class="n">s</span> <span class="bp">↔</span> <span class="bp">∀</span> <span class="n">ε</span> <span class="bp">></span> <span class="mi">0</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">b</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="n">a</span> <span class="bp">∈</span> <span class="n">Metric.ball</span> <span class="n">b</span> <span class="n">ε</span> <span class="o">:=</span> <span class="n">Metric.mem_closure_iff</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">closure</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">Metric.ball</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Metric.mem_closure_iff</span> </pre></div> </div> <p>Do the next exercise without using <cite>mem_closure_iff_seq_limit</cite></p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">u</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">X</span><span class="o">}</span> <span class="o">(</span><span class="n">hu</span> <span class="o">:</span> <span class="n">Tendsto</span> <span class="n">u</span> <span class="n">atTop</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">a</span><span class="o">))</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span><span class="o">}</span> <span class="o">(</span><span class="n">hs</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">n</span><span class="o">,</span> <span class="n">u</span> <span class="n">n</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">)</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">∈</span> <span class="n">closure</span> <span class="n">s</span> <span class="o">:=</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">u</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hu</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">atTop</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">a</span><span class="o">))</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">closure</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Remember from the filters sections that neighborhood filters play a big role in Mathlib.
-
@@ -682,11 +683,11 @@ In the metric space context, the crucial point is that balls provide bases for those filters.The main lemmas here are <code class="docutils literal notranslate"><span class="pre">Metric.nhds_basis_ball</span></code> and <code class="docutils literal notranslate"><span class="pre">Metric.nhds_basis_closedBall</span></code> that claim this for open and closed balls with positive radius. The center point is an implicit argument so we can invoke <code class="docutils literal notranslate"><span class="pre">Filter.HasBasis.mem_iff</span></code> as in the following example.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">X</span><span class="o">}</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span><span class="o">}</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">∈</span> <span class="bp">𝓝</span> <span class="n">x</span> <span class="bp">↔</span> <span class="bp">∃</span> <span class="n">ε</span> <span class="bp">></span> <span class="mi">0</span><span class="o">,</span> <span class="n">Metric.ball</span> <span class="n">x</span> <span class="n">ε</span> <span class="bp">⊆</span> <span class="n">s</span> <span class="o">:=</span> <span class="n">Metric.nhds_basis_ball.mem_iff</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">𝓝</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="n">Metric.ball</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Metric.nhds_basis_ball.mem_iff</span> <span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">X</span><span class="o">}</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span><span class="o">}</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">∈</span> <span class="bp">𝓝</span> <span class="n">x</span> <span class="bp">↔</span> <span class="bp">∃</span> <span class="n">ε</span> <span class="bp">></span> <span class="mi">0</span><span class="o">,</span> <span class="n">Metric.closedBall</span> <span class="n">x</span> <span class="n">ε</span> <span class="bp">⊆</span> <span class="n">s</span> <span class="o">:=</span> <span class="n">Metric.nhds_basis_closedBall.mem_iff</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">𝓝</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="n">Metric.closedBall</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Metric.nhds_basis_closedBall.mem_iff</span> </pre></div> </div> </section>
-
@@ -705,30 +706,30 @@ claims for compact sets in general metric spaces. In the second statement we onlyneed continuity on the given set so we will use <code class="docutils literal notranslate"><span class="pre">ContinuousOn</span></code> instead of <code class="docutils literal notranslate"><span class="pre">Continuous</span></code>, and we will give separate statements for the minimum and the maximum. Of course all these results are deduced from more general versions, some of which will be discussed in later sections.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">IsCompact</span> <span class="o">(</span><span class="n">Set.Icc</span> <span class="mi">0</span> <span class="mi">1</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:=</span> <span class="n">isCompact_Icc</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsCompact</span><span class="w"> </span><span class="o">(</span><span class="n">Set.Icc</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">isCompact_Icc</span> <span class="kd">example</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span><span class="o">}</span> <span class="o">(</span><span class="n">hs</span> <span class="o">:</span> <span class="n">IsCompact</span> <span class="n">s</span><span class="o">)</span> <span class="o">{</span><span class="n">u</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">X</span><span class="o">}</span> <span class="o">(</span><span class="n">hu</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">n</span><span class="o">,</span> <span class="n">u</span> <span class="n">n</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">a</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">φ</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">ℕ</span><span class="o">,</span> <span class="n">StrictMono</span> <span class="n">φ</span> <span class="bp">∧</span> <span class="n">Tendsto</span> <span class="o">(</span><span class="n">u</span> <span class="bp">∘</span> <span class="n">φ</span><span class="o">)</span> <span class="n">atTop</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">a</span><span class="o">)</span> <span class="o">:=</span> <span class="n">hs.tendsto_subseq</span> <span class="n">hu</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsCompact</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">u</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hu</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℕ</span><span class="o">,</span><span class="w"> </span><span class="n">StrictMono</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="bp">∘</span><span class="w"> </span><span class="n">φ</span><span class="o">)</span><span class="w"> </span><span class="n">atTop</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">hs.tendsto_subseq</span><span class="w"> </span><span class="n">hu</span> <span class="kd">example</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span><span class="o">}</span> <span class="o">(</span><span class="n">hs</span> <span class="o">:</span> <span class="n">IsCompact</span> <span class="n">s</span><span class="o">)</span> <span class="o">(</span><span class="n">hs'</span> <span class="o">:</span> <span class="n">s.Nonempty</span><span class="o">)</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">hfs</span> <span class="o">:</span> <span class="n">ContinuousOn</span> <span class="n">f</span> <span class="n">s</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">y</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">≤</span> <span class="n">f</span> <span class="n">y</span> <span class="o">:=</span> <span class="n">hs.exists_isMinOn</span> <span class="n">hs'</span> <span class="n">hfs</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsCompact</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hs'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s.Nonempty</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span> <span class="w"> </span><span class="o">(</span><span class="n">hfs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ContinuousOn</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">hs.exists_isMinOn</span><span class="w"> </span><span class="n">hs'</span><span class="w"> </span><span class="n">hfs</span> <span class="kd">example</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span><span class="o">}</span> <span class="o">(</span><span class="n">hs</span> <span class="o">:</span> <span class="n">IsCompact</span> <span class="n">s</span><span class="o">)</span> <span class="o">(</span><span class="n">hs'</span> <span class="o">:</span> <span class="n">s.Nonempty</span><span class="o">)</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">hfs</span> <span class="o">:</span> <span class="n">ContinuousOn</span> <span class="n">f</span> <span class="n">s</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">y</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="n">f</span> <span class="n">y</span> <span class="bp">≤</span> <span class="n">f</span> <span class="n">x</span> <span class="o">:=</span> <span class="n">hs.exists_isMaxOn</span> <span class="n">hs'</span> <span class="n">hfs</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsCompact</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hs'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s.Nonempty</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span> <span class="w"> </span><span class="o">(</span><span class="n">hfs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ContinuousOn</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">hs.exists_isMaxOn</span><span class="w"> </span><span class="n">hs'</span><span class="w"> </span><span class="n">hfs</span> <span class="kd">example</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span><span class="o">}</span> <span class="o">(</span><span class="n">hs</span> <span class="o">:</span> <span class="n">IsCompact</span> <span class="n">s</span><span class="o">)</span> <span class="o">:</span> <span class="n">IsClosed</span> <span class="n">s</span> <span class="o">:=</span> <span class="n">hs.isClosed</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsCompact</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsClosed</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">hs.isClosed</span> </pre></div> </div> <p>We can also specify that a metric spaces is globally compact, using an extra <code class="docutils literal notranslate"><span class="pre">Prop</span></code>-valued type class:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">X</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">MetricSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">[</span><span class="n">CompactSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">:</span> <span class="n">IsCompact</span> <span class="o">(</span><span class="n">univ</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span><span class="o">)</span> <span class="o">:=</span> <span class="n">isCompact_univ</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">X</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">MetricSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">CompactSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsCompact</span><span class="w"> </span><span class="o">(</span><span class="n">univ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">isCompact_univ</span> </pre></div> </div> <p>In a compact metric space any closed set is compact, this is <code class="docutils literal notranslate"><span class="pre">IsClosed.isCompact</span></code>.</p>
-
@@ -738,10 +739,10 @@ <h3><span class="section-number">10.2.4. </span>Uniformly continuous functions<a class="headerlink" href="#uniformly-continuous-functions" title="Link to this heading"></a></h3><p>We now turn to uniformity notions on metric spaces : uniformly continuous functions, Cauchy sequences and completeness. Again those are defined in a more general context but we have lemmas in the metric name space to access their elementary definitions. We start with uniform continuity.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">X</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">MetricSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">{</span><span class="n">Y</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">MetricSpace</span> <span class="n">Y</span><span class="o">]</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">}</span> <span class="o">:</span> <span class="n">UniformContinuous</span> <span class="n">f</span> <span class="bp">↔</span> <span class="bp">∀</span> <span class="n">ε</span> <span class="bp">></span> <span class="mi">0</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">δ</span> <span class="bp">></span> <span class="mi">0</span><span class="o">,</span> <span class="bp">∀</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">X</span><span class="o">},</span> <span class="n">dist</span> <span class="n">a</span> <span class="n">b</span> <span class="bp"><</span> <span class="n">δ</span> <span class="bp">→</span> <span class="n">dist</span> <span class="o">(</span><span class="n">f</span> <span class="n">a</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="n">b</span><span class="o">)</span> <span class="bp"><</span> <span class="n">ε</span> <span class="o">:=</span> <span class="n">Metric.uniformContinuous_iff</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">X</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">MetricSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">Y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">MetricSpace</span><span class="w"> </span><span class="n">Y</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">}</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">UniformContinuous</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">↔</span> <span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">δ</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">},</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">δ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Metric.uniformContinuous_iff</span> </pre></div> </div> <p>In order to practice manipulating all those definitions, we will prove that continuous
-
@@ -757,10 +758,10 @@ <p>Then we discuss two possibilities using <code class="docutils literal notranslate"><span class="pre">eq_empty_or_nonempty</span></code>.If <code class="docutils literal notranslate"><span class="pre">K</span></code> is empty then we are clearly done (we can set <code class="docutils literal notranslate"><span class="pre">δ</span> <span class="pre">=</span> <span class="pre">1</span></code> for instance). So let’s assume <code class="docutils literal notranslate"><span class="pre">K</span></code> is not empty, and use the extreme value theorem to choose <code class="docutils literal notranslate"><span class="pre">(x₀,</span> <span class="pre">x₁)</span></code> attaining the infimum of the distance function on <code class="docutils literal notranslate"><span class="pre">K</span></code>. We can then set <code class="docutils literal notranslate"><span class="pre">δ</span> <span class="pre">=</span> <span class="pre">dist</span> <span class="pre">x₀</span> <span class="pre">x₁</span></code> and check everything works.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">X</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">MetricSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">[</span><span class="n">CompactSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">{</span><span class="n">Y</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">MetricSpace</span> <span class="n">Y</span><span class="o">]</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">}</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="n">UniformContinuous</span> <span class="n">f</span> <span class="o">:=</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">X</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">MetricSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">CompactSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span> <span class="w"> </span><span class="o">{</span><span class="n">Y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">MetricSpace</span><span class="w"> </span><span class="n">Y</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">}</span> <span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">UniformContinuous</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> </section>
-
@@ -770,88 +771,88 @@ <p>A Cauchy sequence in a metric space is a sequence whose terms get closer and closer to each other.There are a couple of equivalent ways to state that idea. In particular converging sequences are Cauchy. The converse is true only in so-called <em>complete</em> spaces.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">u</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">X</span><span class="o">)</span> <span class="o">:</span> <span class="n">CauchySeq</span> <span class="n">u</span> <span class="bp">↔</span> <span class="bp">∀</span> <span class="n">ε</span> <span class="bp">></span> <span class="mi">0</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">N</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">m</span> <span class="bp">≥</span> <span class="n">N</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">n</span> <span class="bp">≥</span> <span class="n">N</span><span class="o">,</span> <span class="n">dist</span> <span class="o">(</span><span class="n">u</span> <span class="n">m</span><span class="o">)</span> <span class="o">(</span><span class="n">u</span> <span class="n">n</span><span class="o">)</span> <span class="bp"><</span> <span class="n">ε</span> <span class="o">:=</span> <span class="n">Metric.cauchySeq_iff</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">CauchySeq</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="n">m</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Metric.cauchySeq_iff</span> <span class="kd">example</span> <span class="o">(</span><span class="n">u</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">X</span><span class="o">)</span> <span class="o">:</span> <span class="n">CauchySeq</span> <span class="n">u</span> <span class="bp">↔</span> <span class="bp">∀</span> <span class="n">ε</span> <span class="bp">></span> <span class="mi">0</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">N</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">n</span> <span class="bp">≥</span> <span class="n">N</span><span class="o">,</span> <span class="n">dist</span> <span class="o">(</span><span class="n">u</span> <span class="n">n</span><span class="o">)</span> <span class="o">(</span><span class="n">u</span> <span class="n">N</span><span class="o">)</span> <span class="bp"><</span> <span class="n">ε</span> <span class="o">:=</span> <span class="n">Metric.cauchySeq_iff'</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">CauchySeq</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="n">N</span><span class="o">)</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Metric.cauchySeq_iff'</span> <span class="kd">example</span> <span class="o">[</span><span class="n">CompleteSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">(</span><span class="n">u</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">X</span><span class="o">)</span> <span class="o">(</span><span class="n">hu</span> <span class="o">:</span> <span class="n">CauchySeq</span> <span class="n">u</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span><span class="o">,</span> <span class="n">Tendsto</span> <span class="n">u</span> <span class="n">atTop</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">x</span><span class="o">)</span> <span class="o">:=</span> <span class="n">cauchySeq_tendsto_of_complete</span> <span class="n">hu</span> <span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">CompleteSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hu</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">CauchySeq</span><span class="w"> </span><span class="n">u</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">atTop</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">cauchySeq_tendsto_of_complete</span><span class="w"> </span><span class="n">hu</span> </pre></div> </div> <p>We’ll practice using this definition by proving a convenient criterion which is a special case of a criterion appearing in Mathlib. This is also a good opportunity to practice using big sums in a geometric context. In addition to the explanations from the filters section, you will probably need <code class="docutils literal notranslate"><span class="pre">tendsto_pow_atTop_nhds_zero_of_lt_one</span></code>, <code class="docutils literal notranslate"><span class="pre">Tendsto.mul</span></code> and <code class="docutils literal notranslate"><span class="pre">dist_le_range_sum_dist</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">cauchySeq_of_le_geometric_two'</span> <span class="o">{</span><span class="n">u</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">X</span><span class="o">}</span> <span class="o">(</span><span class="n">hu</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">,</span> <span class="n">dist</span> <span class="o">(</span><span class="n">u</span> <span class="n">n</span><span class="o">)</span> <span class="o">(</span><span class="n">u</span> <span class="o">(</span><span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">))</span> <span class="bp">≤</span> <span class="o">(</span><span class="mi">1</span> <span class="bp">/</span> <span class="mi">2</span><span class="o">)</span> <span class="bp">^</span> <span class="n">n</span><span class="o">)</span> <span class="o">:</span> <span class="n">CauchySeq</span> <span class="n">u</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">Metric.cauchySeq_iff'</span><span class="o">]</span> <span class="n">intro</span> <span class="n">ε</span> <span class="n">ε_pos</span> <span class="n">obtain</span> <span class="o">⟨</span><span class="n">N</span><span class="o">,</span> <span class="n">hN</span><span class="o">⟩</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">N</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">,</span> <span class="mi">1</span> <span class="bp">/</span> <span class="mi">2</span> <span class="bp">^</span> <span class="n">N</span> <span class="bp">*</span> <span class="mi">2</span> <span class="bp"><</span> <span class="n">ε</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="n">use</span> <span class="n">N</span> <span class="n">intro</span> <span class="n">n</span> <span class="n">hn</span> <span class="n">obtain</span> <span class="o">⟨</span><span class="n">k</span><span class="o">,</span> <span class="n">rfl</span> <span class="o">:</span> <span class="n">n</span> <span class="bp">=</span> <span class="n">N</span> <span class="bp">+</span> <span class="n">k</span><span class="o">⟩</span> <span class="o">:=</span> <span class="n">le_iff_exists_add.mp</span> <span class="n">hn</span> <span class="k">calc</span> <span class="n">dist</span> <span class="o">(</span><span class="n">u</span> <span class="o">(</span><span class="n">N</span> <span class="bp">+</span> <span class="n">k</span><span class="o">))</span> <span class="o">(</span><span class="n">u</span> <span class="n">N</span><span class="o">)</span> <span class="bp">=</span> <span class="n">dist</span> <span class="o">(</span><span class="n">u</span> <span class="o">(</span><span class="n">N</span> <span class="bp">+</span> <span class="mi">0</span><span class="o">))</span> <span class="o">(</span><span class="n">u</span> <span class="o">(</span><span class="n">N</span> <span class="bp">+</span> <span class="n">k</span><span class="o">))</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">_</span> <span class="bp">≤</span> <span class="bp">∑</span> <span class="n">i</span> <span class="k">in</span> <span class="n">range</span> <span class="n">k</span><span class="o">,</span> <span class="n">dist</span> <span class="o">(</span><span class="n">u</span> <span class="o">(</span><span class="n">N</span> <span class="bp">+</span> <span class="n">i</span><span class="o">))</span> <span class="o">(</span><span class="n">u</span> <span class="o">(</span><span class="n">N</span> <span class="bp">+</span> <span class="o">(</span><span class="n">i</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">)))</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">_</span> <span class="bp">≤</span> <span class="bp">∑</span> <span class="n">i</span> <span class="k">in</span> <span class="n">range</span> <span class="n">k</span><span class="o">,</span> <span class="o">(</span><span class="mi">1</span> <span class="bp">/</span> <span class="mi">2</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="bp">^</span> <span class="o">(</span><span class="n">N</span> <span class="bp">+</span> <span class="n">i</span><span class="o">)</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">_</span> <span class="bp">=</span> <span class="mi">1</span> <span class="bp">/</span> <span class="mi">2</span> <span class="bp">^</span> <span class="n">N</span> <span class="bp">*</span> <span class="bp">∑</span> <span class="n">i</span> <span class="k">in</span> <span class="n">range</span> <span class="n">k</span><span class="o">,</span> <span class="o">(</span><span class="mi">1</span> <span class="bp">/</span> <span class="mi">2</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="bp">^</span> <span class="n">i</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">_</span> <span class="bp">≤</span> <span class="mi">1</span> <span class="bp">/</span> <span class="mi">2</span> <span class="bp">^</span> <span class="n">N</span> <span class="bp">*</span> <span class="mi">2</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">_</span> <span class="bp"><</span> <span class="n">ε</span> <span class="o">:=</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">cauchySeq_of_le_geometric_two'</span><span class="w"> </span><span class="o">{</span><span class="n">u</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">X</span><span class="o">}</span> <span class="w"> </span><span class="o">(</span><span class="n">hu</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">,</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">))</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="o">(</span><span class="mi">1</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">CauchySeq</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">Metric.cauchySeq_iff'</span><span class="o">]</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="n">ε_pos</span> <span class="w"> </span><span class="n">obtain</span><span class="w"> </span><span class="o">⟨</span><span class="n">N</span><span class="o">,</span><span class="w"> </span><span class="n">hN</span><span class="o">⟩</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">N</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">hn</span> <span class="w"> </span><span class="n">obtain</span><span class="w"> </span><span class="o">⟨</span><span class="n">k</span><span class="o">,</span><span class="w"> </span><span class="n">rfl</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">k</span><span class="o">⟩</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">le_iff_exists_add.mp</span><span class="w"> </span><span class="n">hn</span> <span class="w"> </span><span class="k">calc</span> <span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="o">(</span><span class="n">N</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">k</span><span class="o">))</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="n">N</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="o">(</span><span class="n">N</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">0</span><span class="o">))</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="o">(</span><span class="n">N</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">k</span><span class="o">))</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="bp">∑</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">range</span><span class="w"> </span><span class="n">k</span><span class="o">,</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="o">(</span><span class="n">N</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">i</span><span class="o">))</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="o">(</span><span class="n">N</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="o">(</span><span class="n">i</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)))</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="bp">∑</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">range</span><span class="w"> </span><span class="n">k</span><span class="o">,</span><span class="w"> </span><span class="o">(</span><span class="mi">1</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="o">(</span><span class="n">N</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="bp">∑</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">range</span><span class="w"> </span><span class="n">k</span><span class="o">,</span><span class="w"> </span><span class="o">(</span><span class="mi">1</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="n">N</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>We are ready for the final boss of this section: Baire’s theorem for complete metric spaces! The proof skeleton below shows interesting techniques. It uses the <code class="docutils literal notranslate"><span class="pre">choose</span></code> tactic in its exclamation mark variant (you should experiment with removing this exclamation mark) and it shows how to define something inductively in the middle of a proof using <code class="docutils literal notranslate"><span class="pre">Nat.rec_on</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">Metric</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">Metric</span> <span class="kd">example</span> <span class="o">[</span><span class="n">CompleteSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">Set</span> <span class="n">X</span><span class="o">)</span> <span class="o">(</span><span class="n">ho</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">n</span><span class="o">,</span> <span class="n">IsOpen</span> <span class="o">(</span><span class="n">f</span> <span class="n">n</span><span class="o">))</span> <span class="o">(</span><span class="n">hd</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">n</span><span class="o">,</span> <span class="n">Dense</span> <span class="o">(</span><span class="n">f</span> <span class="n">n</span><span class="o">))</span> <span class="o">:</span> <span class="n">Dense</span> <span class="o">(</span><span class="bp">⋂</span> <span class="n">n</span><span class="o">,</span> <span class="n">f</span> <span class="n">n</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="k">let</span> <span class="n">B</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">ℝ</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">n</span> <span class="bp">↦</span> <span class="o">(</span><span class="mi">1</span> <span class="bp">/</span> <span class="mi">2</span><span class="o">)</span> <span class="bp">^</span> <span class="n">n</span> <span class="k">have</span> <span class="n">Bpos</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">n</span><span class="o">,</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">B</span> <span class="n">n</span> <span class="gr">sorry</span> <span class="c">/-</span><span class="cm"> Translate the density assumption into two functions `center` and `radius` associating</span> <span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">CompleteSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">ho</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">IsOpen</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">n</span><span class="o">))</span><span class="w"> </span><span class="o">(</span><span class="n">hd</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">Dense</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">n</span><span class="o">))</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Dense</span><span class="w"> </span><span class="o">(</span><span class="bp">⋂</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="k">let</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">(</span><span class="mi">1</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="n">n</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">Bpos</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="n">n</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="c">/-</span><span class="cm"> Translate the density assumption into two functions `center` and `radius` associating</span> <span class="cm"> to any n, x, δ, δpos a center and a positive radius such that</span> <span class="cm"> `closedBall center radius` is included both in `f n` and in `closedBall x δ`.</span> <span class="cm"> We can also require `radius ≤ (1/2)^(n+1)`, to ensure we get a Cauchy sequence later. -/</span> <span class="k">have</span> <span class="o">:</span> <span class="bp">∀</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">X</span><span class="o">),</span> <span class="bp">∀</span> <span class="n">δ</span> <span class="bp">></span> <span class="mi">0</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">y</span> <span class="o">:</span> <span class="n">X</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">r</span> <span class="bp">></span> <span class="mi">0</span><span class="o">,</span> <span class="n">r</span> <span class="bp">≤</span> <span class="n">B</span> <span class="o">(</span><span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">)</span> <span class="bp">∧</span> <span class="n">closedBall</span> <span class="n">y</span> <span class="n">r</span> <span class="bp">⊆</span> <span class="n">closedBall</span> <span class="n">x</span> <span class="n">δ</span> <span class="bp">∩</span> <span class="n">f</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="n">choose</span><span class="bp">!</span> <span class="n">center</span> <span class="n">radius</span> <span class="n">Hpos</span> <span class="n">HB</span> <span class="n">Hball</span> <span class="n">using</span> <span class="n">this</span> <span class="n">intro</span> <span class="n">x</span> <span class="n">rw</span> <span class="o">[</span><span class="n">mem_closure_iff_nhds_basis</span> <span class="n">nhds_basis_closedBall</span><span class="o">]</span> <span class="n">intro</span> <span class="n">ε</span> <span class="n">εpos</span> <span class="c">/-</span><span class="cm"> `ε` is positive. We have to find a point in the ball of radius `ε` around `x`</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">),</span> <span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">δ</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">)</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">closedBall</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">closedBall</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">δ</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">choose</span><span class="bp">!</span><span class="w"> </span><span class="n">center</span><span class="w"> </span><span class="n">radius</span><span class="w"> </span><span class="n">Hpos</span><span class="w"> </span><span class="n">HB</span><span class="w"> </span><span class="n">Hball</span><span class="w"> </span><span class="n">using</span><span class="w"> </span><span class="n">this</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">x</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">mem_closure_iff_nhds_basis</span><span class="w"> </span><span class="n">nhds_basis_closedBall</span><span class="o">]</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="n">εpos</span> <span class="w"> </span><span class="c">/-</span><span class="cm"> `ε` is positive. We have to find a point in the ball of radius `ε` around `x`</span> <span class="cm"> belonging to all `f n`. For this, we construct inductively a sequence</span> <span class="cm"> `F n = (c n, r n)` such that the closed ball `closedBall (c n) (r n)` is included</span> <span class="cm"> in the previous ball and in `f n`, and such that `r n` is small enough to ensure</span> <span class="cm"> that `c n` is a Cauchy sequence. Then `c n` converges to a limit which belongs</span> <span class="cm"> to all the `f n`. -/</span> <span class="k">let</span> <span class="n">F</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">X</span> <span class="bp">×</span> <span class="n">ℝ</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">n</span> <span class="bp">↦</span> <span class="n">Nat.recOn</span> <span class="n">n</span> <span class="o">(</span><span class="n">Prod.mk</span> <span class="n">x</span> <span class="o">(</span><span class="n">min</span> <span class="n">ε</span> <span class="o">(</span><span class="n">B</span> <span class="mi">0</span><span class="o">)))</span> <span class="k">fun</span> <span class="n">n</span> <span class="n">p</span> <span class="bp">↦</span> <span class="n">Prod.mk</span> <span class="o">(</span><span class="n">center</span> <span class="n">n</span> <span class="n">p.1</span> <span class="n">p.2</span><span class="o">)</span> <span class="o">(</span><span class="n">radius</span> <span class="n">n</span> <span class="n">p.1</span> <span class="n">p.2</span><span class="o">)</span> <span class="k">let</span> <span class="n">c</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">X</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">n</span> <span class="bp">↦</span> <span class="o">(</span><span class="n">F</span> <span class="n">n</span><span class="o">)</span><span class="bp">.</span><span class="mi">1</span> <span class="k">let</span> <span class="n">r</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">ℝ</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">n</span> <span class="bp">↦</span> <span class="o">(</span><span class="n">F</span> <span class="n">n</span><span class="o">)</span><span class="bp">.</span><span class="mi">2</span> <span class="k">have</span> <span class="n">rpos</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">n</span><span class="o">,</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">r</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="n">rB</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">n</span><span class="o">,</span> <span class="n">r</span> <span class="n">n</span> <span class="bp">≤</span> <span class="n">B</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="n">incl</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">n</span><span class="o">,</span> <span class="n">closedBall</span> <span class="o">(</span><span class="n">c</span> <span class="o">(</span><span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">))</span> <span class="o">(</span><span class="n">r</span> <span class="o">(</span><span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">))</span> <span class="bp">⊆</span> <span class="n">closedBall</span> <span class="o">(</span><span class="n">c</span> <span class="n">n</span><span class="o">)</span> <span class="o">(</span><span class="n">r</span> <span class="n">n</span><span class="o">)</span> <span class="bp">∩</span> <span class="n">f</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="n">cdist</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">n</span><span class="o">,</span> <span class="n">dist</span> <span class="o">(</span><span class="n">c</span> <span class="n">n</span><span class="o">)</span> <span class="o">(</span><span class="n">c</span> <span class="o">(</span><span class="n">n</span> <span class="bp">+</span> <span class="mi">1</span><span class="o">))</span> <span class="bp">≤</span> <span class="n">B</span> <span class="n">n</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="o">:</span> <span class="n">CauchySeq</span> <span class="n">c</span> <span class="o">:=</span> <span class="n">cauchySeq_of_le_geometric_two'</span> <span class="n">cdist</span> <span class="c1">-- as the sequence `c n` is Cauchy in a complete space, it converges to a limit `y`.</span> <span class="n">rcases</span> <span class="n">cauchySeq_tendsto_of_complete</span> <span class="n">this</span> <span class="k">with</span> <span class="o">⟨</span><span class="n">y</span><span class="o">,</span> <span class="n">ylim</span><span class="o">⟩</span> <span class="c1">-- this point `y` will be the desired point. We will check that it belongs to all</span> <span class="c1">-- `f n` and to `ball x ε`.</span> <span class="n">use</span> <span class="n">y</span> <span class="k">have</span> <span class="n">I</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">n</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">m</span> <span class="bp">≥</span> <span class="n">n</span><span class="o">,</span> <span class="n">closedBall</span> <span class="o">(</span><span class="n">c</span> <span class="n">m</span><span class="o">)</span> <span class="o">(</span><span class="n">r</span> <span class="n">m</span><span class="o">)</span> <span class="bp">⊆</span> <span class="n">closedBall</span> <span class="o">(</span><span class="n">c</span> <span class="n">n</span><span class="o">)</span> <span class="o">(</span><span class="n">r</span> <span class="n">n</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="n">yball</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">n</span><span class="o">,</span> <span class="n">y</span> <span class="bp">∈</span> <span class="n">closedBall</span> <span class="o">(</span><span class="n">c</span> <span class="n">n</span><span class="o">)</span> <span class="o">(</span><span class="n">r</span> <span class="n">n</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="gr">sorry</span> <span class="w"> </span><span class="k">let</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">↦</span> <span class="w"> </span><span class="n">Nat.recOn</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">(</span><span class="n">Prod.mk</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">(</span><span class="n">min</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="o">(</span><span class="n">B</span><span class="w"> </span><span class="mi">0</span><span class="o">)))</span> <span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">Prod.mk</span><span class="w"> </span><span class="o">(</span><span class="n">center</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">p</span><span class="bp">.</span><span class="mi">1</span><span class="w"> </span><span class="n">p</span><span class="bp">.</span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">radius</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">p</span><span class="bp">.</span><span class="mi">1</span><span class="w"> </span><span class="n">p</span><span class="bp">.</span><span class="mi">2</span><span class="o">)</span> <span class="w"> </span><span class="k">let</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">(</span><span class="n">F</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="bp">.</span><span class="mi">1</span> <span class="w"> </span><span class="k">let</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="o">(</span><span class="n">F</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="bp">.</span><span class="mi">2</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">rpos</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">rB</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">incl</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">closedBall</span><span class="w"> </span><span class="o">(</span><span class="n">c</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">))</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">))</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">closedBall</span><span class="w"> </span><span class="o">(</span><span class="n">c</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="bp">∩</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">cdist</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="o">(</span><span class="n">c</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">c</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="mi">1</span><span class="o">))</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">B</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">CauchySeq</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">cauchySeq_of_le_geometric_two'</span><span class="w"> </span><span class="n">cdist</span> <span class="w"> </span><span class="c1">-- as the sequence `c n` is Cauchy in a complete space, it converges to a limit `y`.</span> <span class="w"> </span><span class="n">rcases</span><span class="w"> </span><span class="n">cauchySeq_tendsto_of_complete</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="k">with</span><span class="w"> </span><span class="o">⟨</span><span class="n">y</span><span class="o">,</span><span class="w"> </span><span class="n">ylim</span><span class="o">⟩</span> <span class="w"> </span><span class="c1">-- this point `y` will be the desired point. We will check that it belongs to all</span> <span class="w"> </span><span class="c1">-- `f n` and to `ball x ε`.</span> <span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="n">y</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="bp">≥</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">closedBall</span><span class="w"> </span><span class="o">(</span><span class="n">c</span><span class="w"> </span><span class="n">m</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="n">m</span><span class="o">)</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">closedBall</span><span class="w"> </span><span class="o">(</span><span class="n">c</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">yball</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">closedBall</span><span class="w"> </span><span class="o">(</span><span class="n">c</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">r</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> </section>
-
@@ -869,28 +870,28 @@ remember the notion of open sets (or equivalently the notion of closed sets). From this point of view,a topological space is a type equipped with a collection of sets that are called open sets. This collection has to satisfy a number of axioms presented below (this collection is slightly redundant but we will ignore that).</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">X</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">TopologicalSpace</span> <span class="n">X</span><span class="o">]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">X</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">IsOpen</span> <span class="o">(</span><span class="n">univ</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span><span class="o">)</span> <span class="o">:=</span> <span class="n">isOpen_univ</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsOpen</span><span class="w"> </span><span class="o">(</span><span class="n">univ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">isOpen_univ</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">IsOpen</span> <span class="o">(</span><span class="bp">∅</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span><span class="o">)</span> <span class="o">:=</span> <span class="n">isOpen_empty</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsOpen</span><span class="w"> </span><span class="o">(</span><span class="bp">∅</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">isOpen_empty</span> <span class="kd">example</span> <span class="o">{</span><span class="n">ι</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">Set</span> <span class="n">X</span><span class="o">}</span> <span class="o">(</span><span class="n">hs</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">i</span><span class="o">,</span> <span class="n">IsOpen</span> <span class="o">(</span><span class="n">s</span> <span class="n">i</span><span class="o">))</span> <span class="o">:</span> <span class="n">IsOpen</span> <span class="o">(</span><span class="bp">⋃</span> <span class="n">i</span><span class="o">,</span> <span class="n">s</span> <span class="n">i</span><span class="o">)</span> <span class="o">:=</span> <span class="n">isOpen_iUnion</span> <span class="n">hs</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">ι</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">IsOpen</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="n">i</span><span class="o">))</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsOpen</span><span class="w"> </span><span class="o">(</span><span class="bp">⋃</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">isOpen_iUnion</span><span class="w"> </span><span class="n">hs</span> <span class="kd">example</span> <span class="o">{</span><span class="n">ι</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Fintype</span> <span class="n">ι</span><span class="o">]</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">Set</span> <span class="n">X</span><span class="o">}</span> <span class="o">(</span><span class="n">hs</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">i</span><span class="o">,</span> <span class="n">IsOpen</span> <span class="o">(</span><span class="n">s</span> <span class="n">i</span><span class="o">))</span> <span class="o">:</span> <span class="n">IsOpen</span> <span class="o">(</span><span class="bp">⋂</span> <span class="n">i</span><span class="o">,</span> <span class="n">s</span> <span class="n">i</span><span class="o">)</span> <span class="o">:=</span> <span class="n">isOpen_iInter_of_finite</span> <span class="n">hs</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">ι</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Fintype</span><span class="w"> </span><span class="n">ι</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">IsOpen</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="n">i</span><span class="o">))</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">IsOpen</span><span class="w"> </span><span class="o">(</span><span class="bp">⋂</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">isOpen_iInter_of_finite</span><span class="w"> </span><span class="n">hs</span> </pre></div> </div> <p>Closed sets are then defined as sets whose complement is open. A function between topological spaces is (globally) continuous if all preimages of open sets are open.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">Y</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">TopologicalSpace</span> <span class="n">Y</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">Y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">Y</span><span class="o">]</span> <span class="kd">example</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">}</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="n">f</span> <span class="bp">↔</span> <span class="bp">∀</span> <span class="n">s</span><span class="o">,</span> <span class="n">IsOpen</span> <span class="n">s</span> <span class="bp">→</span> <span class="n">IsOpen</span> <span class="o">(</span><span class="n">f</span> <span class="bp">⁻¹'</span> <span class="n">s</span><span class="o">)</span> <span class="o">:=</span> <span class="n">continuous_def</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">IsOpen</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">IsOpen</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">continuous_def</span> </pre></div> </div> <p>With this definition we already see that, compared to metric spaces, topological spaces only remember
-
@@ -908,22 +909,22 @@ that <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">:</span> <span class="pre">X</span> <span class="pre">→</span> <span class="pre">Y</span></code> is continuous at <code class="docutils literal notranslate"><span class="pre">x</span></code>. The purely filtery way is to say that the direct image under<code class="docutils literal notranslate"><span class="pre">f</span></code> of the generalized set of points that are close to <code class="docutils literal notranslate"><span class="pre">x</span></code> is contained in the generalized set of points that are close to <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">x</span></code>. Recall this is spelled either <code class="docutils literal notranslate"><span class="pre">map</span> <span class="pre">f</span> <span class="pre">(𝓝</span> <span class="pre">x)</span> <span class="pre">≤</span> <span class="pre">𝓝</span> <span class="pre">(f</span> <span class="pre">x)</span></code> or <code class="docutils literal notranslate"><span class="pre">Tendsto</span> <span class="pre">f</span> <span class="pre">(𝓝</span> <span class="pre">x)</span> <span class="pre">(𝓝</span> <span class="pre">(f</span> <span class="pre">x))</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">}</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">X</span><span class="o">}</span> <span class="o">:</span> <span class="n">ContinuousAt</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">↔</span> <span class="n">map</span> <span class="n">f</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">x</span><span class="o">)</span> <span class="bp">≤</span> <span class="bp">𝓝</span> <span class="o">(</span><span class="n">f</span> <span class="n">x</span><span class="o">)</span> <span class="o">:=</span> <span class="n">Iff.rfl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ContinuousAt</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">map</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">𝓝</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Iff.rfl</span> </pre></div> </div> <p>One can also spell it using both neighborhoods seen as ordinary sets and a neighborhood filter seen as a generalized set: “for any neighborhood <code class="docutils literal notranslate"><span class="pre">U</span></code> of <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">x</span></code>, all points close to <code class="docutils literal notranslate"><span class="pre">x</span></code> are sent to <code class="docutils literal notranslate"><span class="pre">U</span></code>”. Note that the proof is again <code class="docutils literal notranslate"><span class="pre">iff.rfl</span></code>, this point of view is definitionally equivalent to the previous one.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">}</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">X</span><span class="o">}</span> <span class="o">:</span> <span class="n">ContinuousAt</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">↔</span> <span class="bp">∀</span> <span class="n">U</span> <span class="bp">∈</span> <span class="bp">𝓝</span> <span class="o">(</span><span class="n">f</span> <span class="n">x</span><span class="o">),</span> <span class="bp">∀ᶠ</span> <span class="n">x</span> <span class="k">in</span> <span class="bp">𝓝</span> <span class="n">x</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">U</span> <span class="o">:=</span> <span class="n">Iff.rfl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ContinuousAt</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">𝓝</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="o">),</span><span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">𝓝</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Iff.rfl</span> </pre></div> </div> <p>We now explain how to go from one point of view to the other. In terms of open sets, we can simply define members of <code class="docutils literal notranslate"><span class="pre">𝓝</span> <span class="pre">x</span></code> as sets that contain an open set containing <code class="docutils literal notranslate"><span class="pre">x</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">X</span><span class="o">}</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span><span class="o">}</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">∈</span> <span class="bp">𝓝</span> <span class="n">x</span> <span class="bp">↔</span> <span class="bp">∃</span> <span class="n">t</span><span class="o">,</span> <span class="n">t</span> <span class="bp">⊆</span> <span class="n">s</span> <span class="bp">∧</span> <span class="n">IsOpen</span> <span class="n">t</span> <span class="bp">∧</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">t</span> <span class="o">:=</span> <span class="n">mem_nhds_iff</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">𝓝</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">t</span><span class="o">,</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">IsOpen</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">mem_nhds_iff</span> </pre></div> </div> <p>To go in the other direction we need to discuss the condition that <code class="docutils literal notranslate"><span class="pre">𝓝</span> <span class="pre">:</span> <span class="pre">X</span> <span class="pre">→</span> <span class="pre">Filter</span> <span class="pre">X</span></code> must satisfy
-
@@ -931,17 +932,17 @@ in order to be the neighborhood function of a topology.</p><p>The first constraint is that <code class="docutils literal notranslate"><span class="pre">𝓝</span> <span class="pre">x</span></code>, seen as a generalized set, contains the set <code class="docutils literal notranslate"><span class="pre">{x}</span></code> seen as the generalized set <code class="docutils literal notranslate"><span class="pre">pure</span> <span class="pre">x</span></code> (explaining this weird name would be too much of a digression, so we simply accept it for now). Another way to say it is that if a predicate holds for points close to <code class="docutils literal notranslate"><span class="pre">x</span></code> then it holds at <code class="docutils literal notranslate"><span class="pre">x</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">X</span><span class="o">)</span> <span class="o">:</span> <span class="n">pure</span> <span class="n">x</span> <span class="bp">≤</span> <span class="bp">𝓝</span> <span class="n">x</span> <span class="o">:=</span> <span class="n">pure_le_nhds</span> <span class="n">x</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">pure</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">𝓝</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">pure_le_nhds</span><span class="w"> </span><span class="n">x</span> <span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">X</span><span class="o">)</span> <span class="o">(</span><span class="n">P</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="kt">Prop</span><span class="o">)</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">∀ᶠ</span> <span class="n">y</span> <span class="k">in</span> <span class="bp">𝓝</span> <span class="n">x</span><span class="o">,</span> <span class="n">P</span> <span class="n">y</span><span class="o">)</span> <span class="o">:</span> <span class="n">P</span> <span class="n">x</span> <span class="o">:=</span> <span class="n">h.self_of_nhds</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">P</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="kt">Prop</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">𝓝</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">h.self_of_nhds</span> </pre></div> </div> <p>Then a more subtle requirement is that, for any predicate <code class="docutils literal notranslate"><span class="pre">P</span> <span class="pre">:</span> <span class="pre">X</span> <span class="pre">→</span> <span class="pre">Prop</span></code> and any <code class="docutils literal notranslate"><span class="pre">x</span></code>, if <code class="docutils literal notranslate"><span class="pre">P</span> <span class="pre">y</span></code> holds for <code class="docutils literal notranslate"><span class="pre">y</span></code> close to <code class="docutils literal notranslate"><span class="pre">x</span></code> then for <code class="docutils literal notranslate"><span class="pre">y</span></code> close to <code class="docutils literal notranslate"><span class="pre">x</span></code> and <code class="docutils literal notranslate"><span class="pre">z</span></code> close to <code class="docutils literal notranslate"><span class="pre">y</span></code>, <code class="docutils literal notranslate"><span class="pre">P</span> <span class="pre">z</span></code> holds. More precisely we have:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">P</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="kt">Prop</span><span class="o">}</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">X</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">∀ᶠ</span> <span class="n">y</span> <span class="k">in</span> <span class="bp">𝓝</span> <span class="n">x</span><span class="o">,</span> <span class="n">P</span> <span class="n">y</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∀ᶠ</span> <span class="n">y</span> <span class="k">in</span> <span class="bp">𝓝</span> <span class="n">x</span><span class="o">,</span> <span class="bp">∀ᶠ</span> <span class="n">z</span> <span class="k">in</span> <span class="bp">𝓝</span> <span class="n">y</span><span class="o">,</span> <span class="n">P</span> <span class="n">z</span> <span class="o">:=</span> <span class="n">eventually_eventually_nhds.mpr</span> <span class="n">h</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">P</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="kt">Prop</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">𝓝</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">𝓝</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">𝓝</span><span class="w"> </span><span class="n">y</span><span class="o">,</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">eventually_eventually_nhds.mpr</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>Those two results characterize the functions <code class="docutils literal notranslate"><span class="pre">X</span> <span class="pre">→</span> <span class="pre">Filter</span> <span class="pre">X</span></code> that are neighborhood functions for a topological space
-
@@ -949,10 +950,10 @@ structure on <code class="docutils literal notranslate"><span class="pre">X</span></code>. There is a still a function <code class="docutils literal notranslate"><span class="pre">TopologicalSpace.mkOfNhds</span> <span class="pre">:</span> <span class="pre">(X</span> <span class="pre">→</span> <span class="pre">Filter</span> <span class="pre">X)</span> <span class="pre">→</span> <span class="pre">TopologicalSpace</span> <span class="pre">X</span></code>but it will give back its input as a neighborhood function only if it satisfies the above two constraints. More precisely we have a lemma <code class="docutils literal notranslate"><span class="pre">TopologicalSpace.nhds_mkOfNhds</span></code> saying that in a different way and our next exercise deduces this different way from how we stated it above.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">Filter</span> <span class="n">α</span><span class="o">)</span> <span class="o">(</span><span class="n">H₀</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span><span class="o">,</span> <span class="n">pure</span> <span class="n">a</span> <span class="bp">≤</span> <span class="n">n</span> <span class="n">a</span><span class="o">)</span> <span class="o">(</span><span class="n">H</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span> <span class="o">:</span> <span class="n">α</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">p</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="kt">Prop</span><span class="o">,</span> <span class="o">(</span><span class="bp">∀ᶠ</span> <span class="n">x</span> <span class="k">in</span> <span class="n">n</span> <span class="n">a</span><span class="o">,</span> <span class="n">p</span> <span class="n">x</span><span class="o">)</span> <span class="bp">→</span> <span class="bp">∀ᶠ</span> <span class="n">y</span> <span class="k">in</span> <span class="n">n</span> <span class="n">a</span><span class="o">,</span> <span class="bp">∀ᶠ</span> <span class="n">x</span> <span class="k">in</span> <span class="n">n</span> <span class="n">y</span><span class="o">,</span> <span class="n">p</span> <span class="n">x</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">a</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">s</span> <span class="bp">∈</span> <span class="n">n</span> <span class="n">a</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">t</span> <span class="bp">∈</span> <span class="n">n</span> <span class="n">a</span><span class="o">,</span> <span class="n">t</span> <span class="bp">⊆</span> <span class="n">s</span> <span class="bp">∧</span> <span class="bp">∀</span> <span class="n">a'</span> <span class="bp">∈</span> <span class="n">t</span><span class="o">,</span> <span class="n">s</span> <span class="bp">∈</span> <span class="n">n</span> <span class="n">a'</span> <span class="o">:=</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">H₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">pure</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">a</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="kt">Prop</span><span class="o">,</span><span class="w"> </span><span class="o">(</span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">y</span><span class="o">,</span><span class="w"> </span><span class="n">p</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a'</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">t</span><span class="o">,</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">a'</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Note that <code class="docutils literal notranslate"><span class="pre">TopologicalSpace.mkOfNhds</span></code> is not so frequently used, but it still good to know in what
-
@@ -974,17 +975,17 @@ <code class="docutils literal notranslate"><span class="pre">ℝ</span> <span class="pre">→</span> <span class="pre">ℝ</span></code> that gives this notion of convergence. Relatedly, there is no distance ensuring thata map <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">:</span> <span class="pre">X</span> <span class="pre">→</span> <span class="pre">(ℝ</span> <span class="pre">→</span> <span class="pre">ℝ)</span></code> is continuous if and only if <code class="docutils literal notranslate"><span class="pre">fun</span> <span class="pre">x</span> <span class="pre">↦</span> <span class="pre">f</span> <span class="pre">x</span> <span class="pre">t</span></code> is continuous for every <code class="docutils literal notranslate"><span class="pre">t</span> <span class="pre">:</span> <span class="pre">ℝ</span></code>.</p> <p>We now review the data used to solve all those issues. First we can use any map <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">:</span> <span class="pre">X</span> <span class="pre">→</span> <span class="pre">Y</span></code> to push or pull topologies from one side to the other. Those two operations form a Galois connection.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">X</span> <span class="n">Y</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">X</span><span class="w"> </span><span class="n">Y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="kd">example</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">)</span> <span class="o">:</span> <span class="n">TopologicalSpace</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">TopologicalSpace</span> <span class="n">Y</span> <span class="o">:=</span> <span class="n">TopologicalSpace.coinduced</span> <span class="n">f</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">Y</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">TopologicalSpace.coinduced</span><span class="w"> </span><span class="n">f</span> <span class="kd">example</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">)</span> <span class="o">:</span> <span class="n">TopologicalSpace</span> <span class="n">Y</span> <span class="bp">→</span> <span class="n">TopologicalSpace</span> <span class="n">X</span> <span class="o">:=</span> <span class="n">TopologicalSpace.induced</span> <span class="n">f</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">Y</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">TopologicalSpace.induced</span><span class="w"> </span><span class="n">f</span> <span class="kd">example</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">)</span> <span class="o">(</span><span class="n">T_X</span> <span class="o">:</span> <span class="n">TopologicalSpace</span> <span class="n">X</span><span class="o">)</span> <span class="o">(</span><span class="n">T_Y</span> <span class="o">:</span> <span class="n">TopologicalSpace</span> <span class="n">Y</span><span class="o">)</span> <span class="o">:</span> <span class="n">TopologicalSpace.coinduced</span> <span class="n">f</span> <span class="n">T_X</span> <span class="bp">≤</span> <span class="n">T_Y</span> <span class="bp">↔</span> <span class="n">T_X</span> <span class="bp">≤</span> <span class="n">TopologicalSpace.induced</span> <span class="n">f</span> <span class="n">T_Y</span> <span class="o">:=</span> <span class="n">coinduced_le_iff_le_induced</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">T_X</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">T_Y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">Y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">TopologicalSpace.coinduced</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">T_X</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">T_Y</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">T_X</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">TopologicalSpace.induced</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">T_Y</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">coinduced_le_iff_le_induced</span> </pre></div> </div> <p>Those operations are compatible with composition of functions.
-
@@ -1000,14 +1001,14 @@ <code class="docutils literal notranslate"><span class="pre">fun</span> <span class="pre">T</span> <span class="pre">:</span> <span class="pre">TopologicalSpace</span> <span class="pre">X</span> <span class="pre">↦</span> <span class="pre">@nhds</span> <span class="pre">X</span> <span class="pre">T</span> <span class="pre">x</span></code> to be order preserving.And we know the order relation on <code class="docutils literal notranslate"><span class="pre">Filter</span> <span class="pre">X</span></code> is designed to ensure an order preserving <code class="docutils literal notranslate"><span class="pre">principal</span> <span class="pre">:</span> <span class="pre">Set</span> <span class="pre">X</span> <span class="pre">→</span> <span class="pre">Filter</span> <span class="pre">X</span></code>, allowing to see filters as generalized sets. So the order relation we do use on <code class="docutils literal notranslate"><span class="pre">TopologicalSpace</span> <span class="pre">X</span></code> is opposite to the one coming from <code class="docutils literal notranslate"><span class="pre">Set</span> <span class="pre">(Set</span> <span class="pre">X)</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">T</span> <span class="n">T'</span> <span class="o">:</span> <span class="n">TopologicalSpace</span> <span class="n">X</span><span class="o">}</span> <span class="o">:</span> <span class="n">T</span> <span class="bp">≤</span> <span class="n">T'</span> <span class="bp">↔</span> <span class="bp">∀</span> <span class="n">s</span><span class="o">,</span> <span class="n">T'.IsOpen</span> <span class="n">s</span> <span class="bp">→</span> <span class="n">T.IsOpen</span> <span class="n">s</span> <span class="o">:=</span> <span class="n">Iff.rfl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">T</span><span class="w"> </span><span class="n">T'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">T</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">T'</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">T'.IsOpen</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">T.IsOpen</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Iff.rfl</span> </pre></div> </div> <p>Now we can recover continuity by combining the push-forward (or pull-back) operation with the order relation.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">T_X</span> <span class="o">:</span> <span class="n">TopologicalSpace</span> <span class="n">X</span><span class="o">)</span> <span class="o">(</span><span class="n">T_Y</span> <span class="o">:</span> <span class="n">TopologicalSpace</span> <span class="n">Y</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">)</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="n">f</span> <span class="bp">↔</span> <span class="n">TopologicalSpace.coinduced</span> <span class="n">f</span> <span class="n">T_X</span> <span class="bp">≤</span> <span class="n">T_Y</span> <span class="o">:=</span> <span class="n">continuous_iff_coinduced_le</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">T_X</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">T_Y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">Y</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">TopologicalSpace.coinduced</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">T_X</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">T_Y</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">continuous_iff_coinduced_le</span> </pre></div> </div> <p>With this definition and the compatibility of push-forward and composition, we
-
@@ -1018,11 +1019,11 @@ <div class="math notranslate nohighlight">\[\begin{split}g \text{ continuous } &⇔ g_*(f_*T_X) ≤ T_Z \\ &⇔ (g ∘ f)_* T_X ≤ T_Z \\ &⇔ g ∘ f \text{ continuous}\end{split}\]</div> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">Z</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">)</span> <span class="o">(</span><span class="n">T_X</span> <span class="o">:</span> <span class="n">TopologicalSpace</span> <span class="n">X</span><span class="o">)</span> <span class="o">(</span><span class="n">T_Z</span> <span class="o">:</span> <span class="n">TopologicalSpace</span> <span class="n">Z</span><span class="o">)</span> <span class="o">(</span><span class="n">g</span> <span class="o">:</span> <span class="n">Y</span> <span class="bp">→</span> <span class="n">Z</span><span class="o">)</span> <span class="o">:</span> <span class="bp">@</span><span class="n">Continuous</span> <span class="n">Y</span> <span class="n">Z</span> <span class="o">(</span><span class="n">TopologicalSpace.coinduced</span> <span class="n">f</span> <span class="n">T_X</span><span class="o">)</span> <span class="n">T_Z</span> <span class="n">g</span> <span class="bp">↔</span> <span class="bp">@</span><span class="n">Continuous</span> <span class="n">X</span> <span class="n">Z</span> <span class="n">T_X</span> <span class="n">T_Z</span> <span class="o">(</span><span class="n">g</span> <span class="bp">∘</span> <span class="n">f</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">rw</span> <span class="o">[</span><span class="n">continuous_iff_coinduced_le</span><span class="o">,</span> <span class="n">coinduced_compose</span><span class="o">,</span> <span class="n">continuous_iff_coinduced_le</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">Z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">T_X</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">T_Z</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">Z</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Y</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Z</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">@</span><span class="n">Continuous</span><span class="w"> </span><span class="n">Y</span><span class="w"> </span><span class="n">Z</span><span class="w"> </span><span class="o">(</span><span class="n">TopologicalSpace.coinduced</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">T_X</span><span class="o">)</span><span class="w"> </span><span class="n">T_Z</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">↔</span> <span class="w"> </span><span class="bp">@</span><span class="n">Continuous</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="n">Z</span><span class="w"> </span><span class="n">T_X</span><span class="w"> </span><span class="n">T_Z</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="bp">∘</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">rw</span><span class="w"> </span><span class="o">[</span><span class="n">continuous_iff_coinduced_le</span><span class="o">,</span><span class="w"> </span><span class="n">coinduced_compose</span><span class="o">,</span><span class="w"> </span><span class="n">continuous_iff_coinduced_le</span><span class="o">]</span> </pre></div> </div> <p>So we already get quotient topologies (using the projection map as <code class="docutils literal notranslate"><span class="pre">f</span></code>). This wasn’t using that
-
@@ -1039,10 +1040,10 @@ &⇔ ∀ i, (p_i)_* f_* T_Z ≤ T_{X_i}\\&⇔ ∀ i, f_* T_Z ≤ (p_i)^*T_{X_i}\\ &⇔ f_* T_Z ≤ \inf \left[(p_i)^*T_{X_i}\right]\end{split}\]</div> <p>So we see that what is the topology we want on <code class="docutils literal notranslate"><span class="pre">Π</span> <span class="pre">i,</span> <span class="pre">X</span> <span class="pre">i</span></code>:</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">ι</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">)</span> <span class="o">(</span><span class="n">X</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">)</span> <span class="o">(</span><span class="n">T_X</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">i</span><span class="o">,</span> <span class="n">TopologicalSpace</span> <span class="o">(</span><span class="n">X</span> <span class="n">i</span><span class="o">))</span> <span class="o">:</span> <span class="o">(</span><span class="k">Pi</span><span class="bp">.</span><span class="n">topologicalSpace</span> <span class="o">:</span> <span class="n">TopologicalSpace</span> <span class="o">(</span><span class="bp">∀</span> <span class="n">i</span><span class="o">,</span> <span class="n">X</span> <span class="n">i</span><span class="o">))</span> <span class="bp">=</span> <span class="bp">⨅</span> <span class="n">i</span><span class="o">,</span> <span class="n">TopologicalSpace.induced</span> <span class="o">(</span><span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">x</span> <span class="n">i</span><span class="o">)</span> <span class="o">(</span><span class="n">T_X</span> <span class="n">i</span><span class="o">)</span> <span class="o">:=</span> <span class="n">rfl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">ι</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">X</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">T_X</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="o">(</span><span class="n">X</span><span class="w"> </span><span class="n">i</span><span class="o">))</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="o">(</span><span class="k">Pi</span><span class="bp">.</span><span class="n">topologicalSpace</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="o">(</span><span class="bp">∀</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="n">i</span><span class="o">))</span><span class="w"> </span><span class="bp">=</span> <span class="w"> </span><span class="bp">⨅</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">TopologicalSpace.induced</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">T_X</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> </pre></div> </div> <p>This ends our tour of how Mathlib thinks that topological spaces fix defects of the theory of metric spaces
-
@@ -1057,19 +1058,19 @@ is closer to what metric spaces do. The most important is <code class="docutils literal notranslate"><span class="pre">T2Space</span></code>, also called “Hausdorff”,that will ensure that limits are unique. A stronger separation property is <code class="docutils literal notranslate"><span class="pre">T3Space</span></code> that ensures in addition the <cite>RegularSpace</cite> property: each point has a basis of closed neighborhoods.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">[</span><span class="n">TopologicalSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">[</span><span class="n">T2Space</span> <span class="n">X</span><span class="o">]</span> <span class="o">{</span><span class="n">u</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">X</span><span class="o">}</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">X</span><span class="o">}</span> <span class="o">(</span><span class="n">ha</span> <span class="o">:</span> <span class="n">Tendsto</span> <span class="n">u</span> <span class="n">atTop</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">a</span><span class="o">))</span> <span class="o">(</span><span class="n">hb</span> <span class="o">:</span> <span class="n">Tendsto</span> <span class="n">u</span> <span class="n">atTop</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">b</span><span class="o">))</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">=</span> <span class="n">b</span> <span class="o">:=</span> <span class="n">tendsto_nhds_unique</span> <span class="n">ha</span> <span class="n">hb</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">T2Space</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">u</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">ha</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">atTop</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">a</span><span class="o">))</span> <span class="w"> </span><span class="o">(</span><span class="n">hb</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">atTop</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">b</span><span class="o">))</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">tendsto_nhds_unique</span><span class="w"> </span><span class="n">ha</span><span class="w"> </span><span class="n">hb</span> <span class="kd">example</span> <span class="o">[</span><span class="n">TopologicalSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">[</span><span class="n">RegularSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">X</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">a</span><span class="o">)</span><span class="bp">.</span><span class="n">HasBasis</span> <span class="o">(</span><span class="k">fun</span> <span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span> <span class="bp">↦</span> <span class="n">s</span> <span class="bp">∈</span> <span class="bp">𝓝</span> <span class="n">a</span> <span class="bp">∧</span> <span class="n">IsClosed</span> <span class="n">s</span><span class="o">)</span> <span class="n">id</span> <span class="o">:=</span> <span class="n">closed_nhds_basis</span> <span class="n">a</span> <span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">RegularSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="bp">.</span><span class="n">HasBasis</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">𝓝</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">IsClosed</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">closed_nhds_basis</span><span class="w"> </span><span class="n">a</span> </pre></div> </div> <p>Note that, in every topological space, each point has a basis of open neighborhood, by definition.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">[</span><span class="n">TopologicalSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">X</span><span class="o">}</span> <span class="o">:</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">x</span><span class="o">)</span><span class="bp">.</span><span class="n">HasBasis</span> <span class="o">(</span><span class="k">fun</span> <span class="n">t</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span> <span class="bp">↦</span> <span class="n">t</span> <span class="bp">∈</span> <span class="bp">𝓝</span> <span class="n">x</span> <span class="bp">∧</span> <span class="n">IsOpen</span> <span class="n">t</span><span class="o">)</span> <span class="n">id</span> <span class="o">:=</span> <span class="n">nhds_basis_opens'</span> <span class="n">x</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="bp">.</span><span class="n">HasBasis</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">𝓝</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">IsOpen</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">nhds_basis_opens'</span><span class="w"> </span><span class="n">x</span> </pre></div> </div> <p>Our main goal is now to prove the basic theorem which allows extension by continuity.
-
@@ -1087,11 +1088,11 @@ The assumption “tends to <span class="math notranslate nohighlight">\(x\)</span> while remaining in <span class="math notranslate nohighlight">\(A\)</span>” corresponds to the pull-back filter<code class="docutils literal notranslate"><span class="pre">comap</span> <span class="pre">(↑)</span> <span class="pre">(𝓝</span> <span class="pre">x)</span></code>.</p> <p>Let’s first prove an auxiliary lemma, extracted to simplify the context (in particular we don’t need Y to be a topological space here).</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span> <span class="n">aux</span> <span class="o">{</span><span class="n">X</span> <span class="n">Y</span> <span class="n">A</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">TopologicalSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">{</span><span class="n">c</span> <span class="o">:</span> <span class="n">A</span> <span class="bp">→</span> <span class="n">X</span><span class="o">}</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">A</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">}</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">X</span><span class="o">}</span> <span class="o">{</span><span class="n">F</span> <span class="o">:</span> <span class="n">Filter</span> <span class="n">Y</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">Tendsto</span> <span class="n">f</span> <span class="o">(</span><span class="n">comap</span> <span class="n">c</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">x</span><span class="o">))</span> <span class="n">F</span><span class="o">)</span> <span class="o">{</span><span class="n">V'</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">Y</span><span class="o">}</span> <span class="o">(</span><span class="n">V'_in</span> <span class="o">:</span> <span class="n">V'</span> <span class="bp">∈</span> <span class="n">F</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">V</span> <span class="bp">∈</span> <span class="bp">𝓝</span> <span class="n">x</span><span class="o">,</span> <span class="n">IsOpen</span> <span class="n">V</span> <span class="bp">∧</span> <span class="n">c</span> <span class="bp">⁻¹'</span> <span class="n">V</span> <span class="bp">⊆</span> <span class="n">f</span> <span class="bp">⁻¹'</span> <span class="n">V'</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">theorem</span><span class="w"> </span><span class="n">aux</span><span class="w"> </span><span class="o">{</span><span class="n">X</span><span class="w"> </span><span class="n">Y</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">X</span><span class="o">}</span> <span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">Y</span><span class="o">}</span> <span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">comap</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">x</span><span class="o">))</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">V'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">Y</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">V'_in</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">V'</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">𝓝</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">IsOpen</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="n">V</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⁻¹'</span><span class="w"> </span><span class="n">V'</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>Let’s now turn to the main proof of the extension by continuity theorem.</p>
-
@@ -1117,23 +1118,23 @@ Because we know <code class="docutils literal notranslate"><span class="pre">Tendsto</span> <span class="pre">f</span> <span class="pre">(comap</span> <span class="pre">(↑)</span> <span class="pre">(𝓝</span> <span class="pre">y))</span> <span class="pre">(𝓝</span> <span class="pre">(φ</span> <span class="pre">y))</span></code> this implies<code class="docutils literal notranslate"><span class="pre">φ</span> <span class="pre">y</span> <span class="pre">∈</span> <span class="pre">closure</span> <span class="pre">V'</span></code> and, since <code class="docutils literal notranslate"><span class="pre">V'</span></code> is closed, we have proved <code class="docutils literal notranslate"><span class="pre">φ</span> <span class="pre">y</span> <span class="pre">∈</span> <span class="pre">V'</span></code>.</p> <p>It remains to prove that <code class="docutils literal notranslate"><span class="pre">φ</span></code> extends <code class="docutils literal notranslate"><span class="pre">f</span></code>. This is where the continuity of <code class="docutils literal notranslate"><span class="pre">f</span></code> enters the discussion, together with the fact that <code class="docutils literal notranslate"><span class="pre">Y</span></code> is Hausdorff.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">[</span><span class="n">TopologicalSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">[</span><span class="n">TopologicalSpace</span> <span class="n">Y</span><span class="o">]</span> <span class="o">[</span><span class="n">T3Space</span> <span class="n">Y</span><span class="o">]</span> <span class="o">{</span><span class="n">A</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span><span class="o">}</span> <span class="o">(</span><span class="n">hA</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span><span class="o">,</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">closure</span> <span class="n">A</span><span class="o">)</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">A</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">}</span> <span class="o">(</span><span class="n">f_cont</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="n">f</span><span class="o">)</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="o">:</span> <span class="n">X</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">c</span> <span class="o">:</span> <span class="n">Y</span><span class="o">,</span> <span class="n">Tendsto</span> <span class="n">f</span> <span class="o">(</span><span class="n">comap</span> <span class="o">(</span><span class="bp">↑</span><span class="o">)</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">x</span><span class="o">))</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">c</span><span class="o">))</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">φ</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">,</span> <span class="n">Continuous</span> <span class="n">φ</span> <span class="bp">∧</span> <span class="bp">∀</span> <span class="n">a</span> <span class="o">:</span> <span class="n">A</span><span class="o">,</span> <span class="n">φ</span> <span class="n">a</span> <span class="bp">=</span> <span class="n">f</span> <span class="n">a</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">Y</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">T3Space</span><span class="w"> </span><span class="n">Y</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">A</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">}</span> <span class="w"> </span><span class="o">(</span><span class="n">hA</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">closure</span><span class="w"> </span><span class="n">A</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">f_cont</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="n">f</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Y</span><span class="o">,</span><span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">comap</span><span class="w"> </span><span class="o">(</span><span class="bp">↑</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">x</span><span class="o">))</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">c</span><span class="o">))</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">,</span><span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">A</span><span class="o">,</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="gr">sorry</span> <span class="k">#check</span> <span class="n">HasBasis.tendsto_right_iff</span> <span class="k">#check</span><span class="w"> </span><span class="n">HasBasis.tendsto_right_iff</span> </pre></div> </div> <p>In addition to separation property, the main kind of assumption you can make on a topological space to bring it closer to metric spaces is countability assumption. The main one is first countability asking that every point has a countable neighborhood basis. In particular this ensures that closure of sets can be understood using sequences.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">[</span><span class="n">TopologicalSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">[</span><span class="n">FirstCountableTopology</span> <span class="n">X</span><span class="o">]</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span><span class="o">}</span> <span class="o">{</span><span class="n">a</span> <span class="o">:</span> <span class="n">X</span><span class="o">}</span> <span class="o">:</span> <span class="n">a</span> <span class="bp">∈</span> <span class="n">closure</span> <span class="n">s</span> <span class="bp">↔</span> <span class="bp">∃</span> <span class="n">u</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">X</span><span class="o">,</span> <span class="o">(</span><span class="bp">∀</span> <span class="n">n</span><span class="o">,</span> <span class="n">u</span> <span class="n">n</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">)</span> <span class="bp">∧</span> <span class="n">Tendsto</span> <span class="n">u</span> <span class="n">atTop</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">a</span><span class="o">)</span> <span class="o">:=</span> <span class="n">mem_closure_iff_seq_limit</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">FirstCountableTopology</span><span class="w"> </span><span class="n">X</span><span class="o">]</span> <span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">closure</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">X</span><span class="o">,</span><span class="w"> </span><span class="o">(</span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">atTop</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">mem_closure_iff_seq_limit</span> </pre></div> </div> </section>
-
@@ -1146,14 +1147,14 @@ a point <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">:</span> <span class="pre">X</span></code> is a cluster point of <code class="docutils literal notranslate"><span class="pre">F</span></code> if <code class="docutils literal notranslate"><span class="pre">F</span></code>, seen as a generalized set, has non-empty intersectionwith the generalized set of points that are close to <code class="docutils literal notranslate"><span class="pre">x</span></code>.</p> <p>Then we can say that a set <code class="docutils literal notranslate"><span class="pre">s</span></code> is compact if every nonempty generalized set <code class="docutils literal notranslate"><span class="pre">F</span></code> contained in <code class="docutils literal notranslate"><span class="pre">s</span></code>, i.e. such that <code class="docutils literal notranslate"><span class="pre">F</span> <span class="pre">≤</span> <span class="pre">𝓟</span> <span class="pre">s</span></code>, has a cluster point in <code class="docutils literal notranslate"><span class="pre">s</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">[</span><span class="n">TopologicalSpace</span> <span class="n">X</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">[</span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span> <span class="kd">example</span> <span class="o">{</span><span class="n">F</span> <span class="o">:</span> <span class="n">Filter</span> <span class="n">X</span><span class="o">}</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">X</span><span class="o">}</span> <span class="o">:</span> <span class="n">ClusterPt</span> <span class="n">x</span> <span class="n">F</span> <span class="bp">↔</span> <span class="n">NeBot</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">x</span> <span class="bp">⊓</span> <span class="n">F</span><span class="o">)</span> <span class="o">:=</span> <span class="n">Iff.rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ClusterPt</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">NeBot</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Iff.rfl</span> <span class="kd">example</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span><span class="o">}</span> <span class="o">:</span> <span class="n">IsCompact</span> <span class="n">s</span> <span class="bp">↔</span> <span class="bp">∀</span> <span class="o">(</span><span class="n">F</span> <span class="o">:</span> <span class="n">Filter</span> <span class="n">X</span><span class="o">)</span> <span class="o">[</span><span class="n">NeBot</span> <span class="n">F</span><span class="o">],</span> <span class="n">F</span> <span class="bp">≤</span> <span class="bp">𝓟</span> <span class="n">s</span> <span class="bp">→</span> <span class="bp">∃</span> <span class="n">a</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="n">ClusterPt</span> <span class="n">a</span> <span class="n">F</span> <span class="o">:=</span> <span class="n">Iff.rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">IsCompact</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">(</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">NeBot</span><span class="w"> </span><span class="n">F</span><span class="o">],</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">𝓟</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">ClusterPt</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Iff.rfl</span> </pre></div> </div> <p>For instance if <code class="docutils literal notranslate"><span class="pre">F</span></code> is <code class="docutils literal notranslate"><span class="pre">map</span> <span class="pre">u</span> <span class="pre">atTop</span></code>, the image under <code class="docutils literal notranslate"><span class="pre">u</span> <span class="pre">:</span> <span class="pre">ℕ</span> <span class="pre">→</span> <span class="pre">X</span></code> of <code class="docutils literal notranslate"><span class="pre">atTop</span></code>, the generalized set
-
@@ -1162,36 +1163,36 @@ large enough. Saying that <code class="docutils literal notranslate"><span class="pre">x</span></code> is a cluster point of <code class="docutils literal notranslate"><span class="pre">map</span> <span class="pre">u</span> <span class="pre">atTop</span></code> says the image of very large numbersintersects the set of points that are close to <code class="docutils literal notranslate"><span class="pre">x</span></code>. In case <code class="docutils literal notranslate"><span class="pre">𝓝</span> <span class="pre">x</span></code> has a countable basis, we can interpret this as saying that <code class="docutils literal notranslate"><span class="pre">u</span></code> has a subsequence converging to <code class="docutils literal notranslate"><span class="pre">x</span></code>, and we get back what compactness looks like in metric spaces.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">[</span><span class="n">FirstCountableTopology</span> <span class="n">X</span><span class="o">]</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span><span class="o">}</span> <span class="o">{</span><span class="n">u</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">X</span><span class="o">}</span> <span class="o">(</span><span class="n">hs</span> <span class="o">:</span> <span class="n">IsCompact</span> <span class="n">s</span><span class="o">)</span> <span class="o">(</span><span class="n">hu</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">n</span><span class="o">,</span> <span class="n">u</span> <span class="n">n</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">a</span> <span class="bp">∈</span> <span class="n">s</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">φ</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">ℕ</span><span class="o">,</span> <span class="n">StrictMono</span> <span class="n">φ</span> <span class="bp">∧</span> <span class="n">Tendsto</span> <span class="o">(</span><span class="n">u</span> <span class="bp">∘</span> <span class="n">φ</span><span class="o">)</span> <span class="n">atTop</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="n">a</span><span class="o">)</span> <span class="o">:=</span> <span class="n">hs.tendsto_subseq</span> <span class="n">hu</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">FirstCountableTopology</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">u</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsCompact</span><span class="w"> </span><span class="n">s</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="n">hu</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℕ</span><span class="o">,</span><span class="w"> </span><span class="n">StrictMono</span><span class="w"> </span><span class="n">φ</span><span class="w"> </span><span class="bp">∧</span><span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="o">(</span><span class="n">u</span><span class="w"> </span><span class="bp">∘</span><span class="w"> </span><span class="n">φ</span><span class="o">)</span><span class="w"> </span><span class="n">atTop</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">hs.tendsto_subseq</span><span class="w"> </span><span class="n">hu</span> </pre></div> </div> <p>Cluster points behave nicely with continuous functions.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">[</span><span class="n">TopologicalSpace</span> <span class="n">Y</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">[</span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">Y</span><span class="o">]</span> <span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">X</span><span class="o">}</span> <span class="o">{</span><span class="n">F</span> <span class="o">:</span> <span class="n">Filter</span> <span class="n">X</span><span class="o">}</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="n">Filter</span> <span class="n">Y</span><span class="o">}</span> <span class="o">(</span><span class="n">H</span> <span class="o">:</span> <span class="n">ClusterPt</span> <span class="n">x</span> <span class="n">F</span><span class="o">)</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">}</span> <span class="o">(</span><span class="n">hfx</span> <span class="o">:</span> <span class="n">ContinuousAt</span> <span class="n">f</span> <span class="n">x</span><span class="o">)</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">Tendsto</span> <span class="n">f</span> <span class="n">F</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="n">ClusterPt</span> <span class="o">(</span><span class="n">f</span> <span class="n">x</span><span class="o">)</span> <span class="n">G</span> <span class="o">:=</span> <span class="n">ClusterPt.map</span> <span class="n">H</span> <span class="n">hfx</span> <span class="n">hf</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">Y</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">H</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ClusterPt</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">}</span> <span class="w"> </span><span class="o">(</span><span class="n">hfx</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ContinuousAt</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ClusterPt</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">ClusterPt.map</span><span class="w"> </span><span class="n">H</span><span class="w"> </span><span class="n">hfx</span><span class="w"> </span><span class="n">hf</span> </pre></div> </div> <p>As an exercise, we will prove that the image of a compact set under a continuous map is compact. In addition to what we saw already, you should use <code class="docutils literal notranslate"><span class="pre">Filter.push_pull</span></code> and <code class="docutils literal notranslate"><span class="pre">NeBot.of_map</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">[</span><span class="n">TopologicalSpace</span> <span class="n">Y</span><span class="o">]</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">Y</span><span class="o">}</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="n">f</span><span class="o">)</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span><span class="o">}</span> <span class="o">(</span><span class="n">hs</span> <span class="o">:</span> <span class="n">IsCompact</span> <span class="n">s</span><span class="o">)</span> <span class="o">:</span> <span class="n">IsCompact</span> <span class="o">(</span><span class="n">f</span> <span class="bp">''</span> <span class="n">s</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">intro</span> <span class="n">F</span> <span class="n">F_ne</span> <span class="n">F_le</span> <span class="k">have</span> <span class="n">map_eq</span> <span class="o">:</span> <span class="n">map</span> <span class="n">f</span> <span class="o">(</span><span class="bp">𝓟</span> <span class="n">s</span> <span class="bp">⊓</span> <span class="n">comap</span> <span class="n">f</span> <span class="n">F</span><span class="o">)</span> <span class="bp">=</span> <span class="bp">𝓟</span> <span class="o">(</span><span class="n">f</span> <span class="bp">''</span> <span class="n">s</span><span class="o">)</span> <span class="bp">⊓</span> <span class="n">F</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="n">Hne</span> <span class="o">:</span> <span class="o">(</span><span class="bp">𝓟</span> <span class="n">s</span> <span class="bp">⊓</span> <span class="n">comap</span> <span class="n">f</span> <span class="n">F</span><span class="o">)</span><span class="bp">.</span><span class="n">NeBot</span> <span class="o">:=</span> <span class="kd">by</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="n">Hle</span> <span class="o">:</span> <span class="bp">𝓟</span> <span class="n">s</span> <span class="bp">⊓</span> <span class="n">comap</span> <span class="n">f</span> <span class="n">F</span> <span class="bp">≤</span> <span class="bp">𝓟</span> <span class="n">s</span> <span class="o">:=</span> <span class="n">inf_le_left</span> <span class="gr">sorry</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">Y</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Y</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsCompact</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">IsCompact</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="n">intro</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="n">F_ne</span><span class="w"> </span><span class="n">F_le</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">map_eq</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">map</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">𝓟</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">comap</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">𝓟</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">Hne</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="n">𝓟</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">comap</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="bp">.</span><span class="n">NeBot</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">Hle</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">𝓟</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊓</span><span class="w"> </span><span class="n">comap</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">𝓟</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">inf_le_left</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> <p>One can also express compactness in terms of open covers: <code class="docutils literal notranslate"><span class="pre">s</span></code> is compact if every family of open sets that cover <code class="docutils literal notranslate"><span class="pre">s</span></code> has a finite covering sub-family.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">ι</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">X</span><span class="o">}</span> <span class="o">(</span><span class="n">hs</span> <span class="o">:</span> <span class="n">IsCompact</span> <span class="n">s</span><span class="o">)</span> <span class="o">(</span><span class="n">U</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">Set</span> <span class="n">X</span><span class="o">)</span> <span class="o">(</span><span class="n">hUo</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">i</span><span class="o">,</span> <span class="n">IsOpen</span> <span class="o">(</span><span class="n">U</span> <span class="n">i</span><span class="o">))</span> <span class="o">(</span><span class="n">hsU</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">⊆</span> <span class="bp">⋃</span> <span class="n">i</span><span class="o">,</span> <span class="n">U</span> <span class="n">i</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">t</span> <span class="o">:</span> <span class="n">Finset</span> <span class="n">ι</span><span class="o">,</span> <span class="n">s</span> <span class="bp">⊆</span> <span class="bp">⋃</span> <span class="n">i</span> <span class="bp">∈</span> <span class="n">t</span><span class="o">,</span> <span class="n">U</span> <span class="n">i</span> <span class="o">:=</span> <span class="n">hs.elim_finite_subcover</span> <span class="n">U</span> <span class="n">hUo</span> <span class="n">hsU</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">ι</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsCompact</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">U</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">X</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hUo</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">IsOpen</span><span class="w"> </span><span class="o">(</span><span class="n">U</span><span class="w"> </span><span class="n">i</span><span class="o">))</span> <span class="w"> </span><span class="o">(</span><span class="n">hsU</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="bp">⋃</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Finset</span><span class="w"> </span><span class="n">ι</span><span class="o">,</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="bp">⋃</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">t</span><span class="o">,</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">hs.elim_finite_subcover</span><span class="w"> </span><span class="n">U</span><span class="w"> </span><span class="n">hUo</span><span class="w"> </span><span class="n">hsU</span> </pre></div> </div> </section>
-
-
-
@@ -1,3 +1,5 @@<!DOCTYPE html> <html class="writer-html5" lang="en" data-content_root="./"> <head>
-
@@ -6,18 +8,17 @@<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>11. Differential Calculus — Mathematics in Lean 0.1 documentation</title> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=80d5e7a1" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=86f27845" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" /> <link rel="stylesheet" type="text/css" href="_static/css/custom.css?v=0731ccc3" /> <link rel="shortcut icon" href="_static/favicon.ico"/> <script src="_static/jquery.js?v=8dae8fb0"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=888ff710"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> <script src="_static/jquery.js?v=5d32c60e"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=9bcbadda"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> <script src="_static/js/theme.js"></script> <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" />
-
@@ -112,10 +113,10 @@ <p>Let <code class="docutils literal notranslate"><span class="pre">f</span></code> be a function from the reals to the reals. There is a differencebetween talking about the derivative of <code class="docutils literal notranslate"><span class="pre">f</span></code> at a single point and talking about the derivative function. In Mathlib, the first notion is represented as follows.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">Real</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">Real</span> <span class="sd">/-- The sin function has derivative 1 at 0. -/</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">HasDerivAt</span> <span class="n">sin</span> <span class="mi">1</span> <span class="mi">0</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simpa</span> <span class="n">using</span> <span class="n">hasDerivAt_sin</span> <span class="mi">0</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">HasDerivAt</span><span class="w"> </span><span class="n">sin</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simpa</span><span class="w"> </span><span class="n">using</span><span class="w"> </span><span class="n">hasDerivAt_sin</span><span class="w"> </span><span class="mi">0</span> </pre></div> </div> <p>We can also express that <code class="docutils literal notranslate"><span class="pre">f</span></code> is differentiable at a point without
-
@@ -125,8 +126,8 @@ We specify <code class="docutils literal notranslate"><span class="pre">ℝ</span></code> explicitly because in a slightly more general context,when talking about functions from <code class="docutils literal notranslate"><span class="pre">ℂ</span></code> to <code class="docutils literal notranslate"><span class="pre">ℂ</span></code>, we want to be able to distinguish between being differentiable in the real sense and being differentiable in the sense of the complex derivative.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">DifferentiableAt</span> <span class="n">ℝ</span> <span class="n">sin</span> <span class="n">x</span> <span class="o">:=</span> <span class="o">(</span><span class="n">hasDerivAt_sin</span> <span class="n">x</span><span class="o">)</span><span class="bp">.</span><span class="n">differentiableAt</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">DifferentiableAt</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="n">sin</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">(</span><span class="n">hasDerivAt_sin</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="bp">.</span><span class="n">differentiableAt</span> </pre></div> </div> <p>It would be inconvenient to have to provide a proof of differentiability
-
@@ -134,19 +135,19 @@ every time we want to refer to a derivative.So Mathlib provides a function <code class="docutils literal notranslate"><span class="pre">deriv</span> <span class="pre">f</span> <span class="pre">:</span> <span class="pre">ℝ</span> <span class="pre">→</span> <span class="pre">ℝ</span></code> that is defined for any function <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">:</span> <span class="pre">ℝ</span> <span class="pre">→</span> <span class="pre">ℝ</span></code> but is defined to take the value <code class="docutils literal notranslate"><span class="pre">0</span></code> at any point where <code class="docutils literal notranslate"><span class="pre">f</span></code> is not differentiable.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">{</span><span class="n">x</span> <span class="n">a</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">HasDerivAt</span> <span class="n">f</span> <span class="n">a</span> <span class="n">x</span><span class="o">)</span> <span class="o">:</span> <span class="n">deriv</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">=</span> <span class="n">a</span> <span class="o">:=</span> <span class="n">h.deriv</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">HasDerivAt</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">deriv</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">h.deriv</span> <span class="kd">example</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">¬</span><span class="n">DifferentiableAt</span> <span class="n">ℝ</span> <span class="n">f</span> <span class="n">x</span><span class="o">)</span> <span class="o">:</span> <span class="n">deriv</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="n">deriv_zero_of_not_differentiableAt</span> <span class="n">h</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">¬</span><span class="n">DifferentiableAt</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">deriv</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">deriv_zero_of_not_differentiableAt</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>Of course there are many lemmas about <code class="docutils literal notranslate"><span class="pre">deriv</span></code> that do require differentiability assumptions. For instance, you should think about a counterexample to the next lemma without the differentiability assumptions.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">f</span> <span class="n">g</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">DifferentiableAt</span> <span class="n">ℝ</span> <span class="n">f</span> <span class="n">x</span><span class="o">)</span> <span class="o">(</span><span class="n">hg</span> <span class="o">:</span> <span class="n">DifferentiableAt</span> <span class="n">ℝ</span> <span class="n">g</span> <span class="n">x</span><span class="o">)</span> <span class="o">:</span> <span class="n">deriv</span> <span class="o">(</span><span class="n">f</span> <span class="bp">+</span> <span class="n">g</span><span class="o">)</span> <span class="n">x</span> <span class="bp">=</span> <span class="n">deriv</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">deriv</span> <span class="n">g</span> <span class="n">x</span> <span class="o">:=</span> <span class="n">deriv_add</span> <span class="n">hf</span> <span class="n">hg</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">DifferentiableAt</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">DifferentiableAt</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">deriv</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">deriv</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">deriv</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">deriv_add</span><span class="w"> </span><span class="n">hf</span><span class="w"> </span><span class="n">hg</span> </pre></div> </div> <p>Interestingly, however, there are statements that can avoid differentiability
-
@@ -155,29 +156,29 @@ of the fact that the value of <code class="docutils literal notranslate"><span class="pre">deriv</span></code> defaults to zero when the function isnot differentiable. So making sense of the following statement requires knowing the precise definition of <code class="docutils literal notranslate"><span class="pre">deriv</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">{</span><span class="n">a</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="n">IsLocalMin</span> <span class="n">f</span> <span class="n">a</span><span class="o">)</span> <span class="o">:</span> <span class="n">deriv</span> <span class="n">f</span> <span class="n">a</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="n">h.deriv_eq_zero</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsLocalMin</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">deriv</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">h.deriv_eq_zero</span> </pre></div> </div> <p>We can even state Rolle’s theorem without any differentiability assumptions, which seems even weirder.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">Set</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">Set</span> <span class="kd">example</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">hab</span> <span class="o">:</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">b</span><span class="o">)</span> <span class="o">(</span><span class="n">hfc</span> <span class="o">:</span> <span class="n">ContinuousOn</span> <span class="n">f</span> <span class="o">(</span><span class="n">Icc</span> <span class="n">a</span> <span class="n">b</span><span class="o">))</span> <span class="o">(</span><span class="n">hfI</span> <span class="o">:</span> <span class="n">f</span> <span class="n">a</span> <span class="bp">=</span> <span class="n">f</span> <span class="n">b</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">c</span> <span class="bp">∈</span> <span class="n">Ioo</span> <span class="n">a</span> <span class="n">b</span><span class="o">,</span> <span class="n">deriv</span> <span class="n">f</span> <span class="n">c</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="n">exists_deriv_eq_zero</span> <span class="n">hab</span> <span class="n">hfc</span> <span class="n">hfI</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hab</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hfc</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ContinuousOn</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">Icc</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="o">))</span><span class="w"> </span><span class="o">(</span><span class="n">hfI</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">Ioo</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">deriv</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">exists_deriv_eq_zero</span><span class="w"> </span><span class="n">hab</span><span class="w"> </span><span class="n">hfc</span><span class="w"> </span><span class="n">hfI</span> </pre></div> </div> <p>Of course, this trick does not work for the general mean value theorem.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">hab</span> <span class="o">:</span> <span class="n">a</span> <span class="bp"><</span> <span class="n">b</span><span class="o">)</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">ContinuousOn</span> <span class="n">f</span> <span class="o">(</span><span class="n">Icc</span> <span class="n">a</span> <span class="n">b</span><span class="o">))</span> <span class="o">(</span><span class="n">hf'</span> <span class="o">:</span> <span class="n">DifferentiableOn</span> <span class="n">ℝ</span> <span class="n">f</span> <span class="o">(</span><span class="n">Ioo</span> <span class="n">a</span> <span class="n">b</span><span class="o">))</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">c</span> <span class="bp">∈</span> <span class="n">Ioo</span> <span class="n">a</span> <span class="n">b</span><span class="o">,</span> <span class="n">deriv</span> <span class="n">f</span> <span class="n">c</span> <span class="bp">=</span> <span class="o">(</span><span class="n">f</span> <span class="n">b</span> <span class="bp">-</span> <span class="n">f</span> <span class="n">a</span><span class="o">)</span> <span class="bp">/</span> <span class="o">(</span><span class="n">b</span> <span class="bp">-</span> <span class="n">a</span><span class="o">)</span> <span class="o">:=</span> <span class="n">exists_deriv_eq_slope</span> <span class="n">f</span> <span class="n">hab</span> <span class="n">hf</span> <span class="n">hf'</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hab</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ContinuousOn</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">Icc</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="o">))</span> <span class="w"> </span><span class="o">(</span><span class="n">hf'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">DifferentiableOn</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">Ioo</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="o">))</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">Ioo</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">deriv</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">exists_deriv_eq_slope</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">hab</span><span class="w"> </span><span class="n">hf</span><span class="w"> </span><span class="n">hf'</span> </pre></div> </div> <p>Lean can automatically compute some simple derivatives using the <code class="docutils literal notranslate"><span class="pre">simp</span></code> tactic.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">deriv</span> <span class="o">(</span><span class="k">fun</span> <span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">↦</span> <span class="n">x</span> <span class="bp">^</span> <span class="mi">5</span><span class="o">)</span> <span class="mi">6</span> <span class="bp">=</span> <span class="mi">5</span> <span class="bp">*</span> <span class="mi">6</span> <span class="bp">^</span> <span class="mi">4</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">deriv</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">5</span><span class="o">)</span><span class="w"> </span><span class="mi">6</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="mi">6</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">4</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simp</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">deriv</span> <span class="n">sin</span> <span class="n">π</span> <span class="bp">=</span> <span class="bp">-</span><span class="mi">1</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">simp</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">deriv</span><span class="w"> </span><span class="n">sin</span><span class="w"> </span><span class="n">π</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">-</span><span class="mi">1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">simp</span> </pre></div> </div> </section>
-
@@ -190,41 +191,41 @@ <em>normed vector space</em>, which encapsulates both direction and distance.We start with the notion of a <em>normed group</em>, which is an additive commutative group equipped with a real-valued norm function satisfying the following conditions.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">E</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NormedAddCommGroup</span> <span class="n">E</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">E</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">NormedAddCommGroup</span><span class="w"> </span><span class="n">E</span><span class="o">]</span> <span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">E</span><span class="o">)</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="bp">‖</span><span class="n">x</span><span class="bp">‖</span> <span class="o">:=</span> <span class="n">norm_nonneg</span> <span class="n">x</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="bp">‖</span><span class="n">x</span><span class="bp">‖</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">norm_nonneg</span><span class="w"> </span><span class="n">x</span> <span class="kd">example</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">E</span><span class="o">}</span> <span class="o">:</span> <span class="bp">‖</span><span class="n">x</span><span class="bp">‖</span> <span class="bp">=</span> <span class="mi">0</span> <span class="bp">↔</span> <span class="n">x</span> <span class="bp">=</span> <span class="mi">0</span> <span class="o">:=</span> <span class="n">norm_eq_zero</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">‖</span><span class="n">x</span><span class="bp">‖</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">norm_eq_zero</span> <span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">E</span><span class="o">)</span> <span class="o">:</span> <span class="bp">‖</span><span class="n">x</span> <span class="bp">+</span> <span class="n">y</span><span class="bp">‖</span> <span class="bp">≤</span> <span class="bp">‖</span><span class="n">x</span><span class="bp">‖</span> <span class="bp">+</span> <span class="bp">‖</span><span class="n">y</span><span class="bp">‖</span> <span class="o">:=</span> <span class="n">norm_add_le</span> <span class="n">x</span> <span class="n">y</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">‖</span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="bp">‖</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="bp">‖</span><span class="n">x</span><span class="bp">‖</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="bp">‖</span><span class="n">y</span><span class="bp">‖</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">norm_add_le</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span> </pre></div> </div> <p>Every normed space is a metric space with distance function <span class="math notranslate nohighlight">\(d(x, y) = \| x - y \|\)</span>, and hence it is also a topological space. Lean and Mathlib know this.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">:</span> <span class="n">MetricSpace</span> <span class="n">E</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">infer_instance</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MetricSpace</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">infer_instance</span> <span class="kd">example</span> <span class="o">{</span><span class="n">X</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">TopologicalSpace</span> <span class="n">X</span><span class="o">]</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">X</span> <span class="bp">→</span> <span class="n">E</span><span class="o">}</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="n">f</span><span class="o">)</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="bp">‖</span><span class="n">f</span> <span class="n">x</span><span class="bp">‖</span> <span class="o">:=</span> <span class="n">hf.norm</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">X</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">TopologicalSpace</span><span class="w"> </span><span class="n">X</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">X</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">E</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="bp">‖</span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="bp">‖</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">hf.norm</span> </pre></div> </div> <p>In order to use the notion of a norm with concepts from linear algebra, we add the assumption <code class="docutils literal notranslate"><span class="pre">NormedSpace</span> <span class="pre">ℝ</span> <span class="pre">E</span></code> on top of <code class="docutils literal notranslate"><span class="pre">NormedAddGroup</span> <span class="pre">E</span></code>. This stipulates that <code class="docutils literal notranslate"><span class="pre">E</span></code> is a vector space over <code class="docutils literal notranslate"><span class="pre">ℝ</span></code> and that scalar multiplication satisfies the following condition.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">[</span><span class="n">NormedSpace</span> <span class="n">ℝ</span> <span class="n">E</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">[</span><span class="n">NormedSpace</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="n">E</span><span class="o">]</span> <span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">E</span><span class="o">)</span> <span class="o">:</span> <span class="bp">‖</span><span class="n">a</span> <span class="bp">•</span> <span class="n">x</span><span class="bp">‖</span> <span class="bp">=</span> <span class="bp">|</span><span class="n">a</span><span class="bp">|</span> <span class="bp">*</span> <span class="bp">‖</span><span class="n">x</span><span class="bp">‖</span> <span class="o">:=</span> <span class="n">norm_smul</span> <span class="n">a</span> <span class="n">x</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">‖</span><span class="n">a</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">x</span><span class="bp">‖</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">|</span><span class="n">a</span><span class="bp">|</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="bp">‖</span><span class="n">x</span><span class="bp">‖</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">norm_smul</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">x</span> </pre></div> </div> <p>A complete normed space is known as a <em>Banach space</em>. Every finite-dimensional vector space is complete.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">[</span><span class="n">FiniteDimensional</span> <span class="n">ℝ</span> <span class="n">E</span><span class="o">]</span> <span class="o">:</span> <span class="n">CompleteSpace</span> <span class="n">E</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">infer_instance</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">[</span><span class="n">FiniteDimensional</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="n">E</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">CompleteSpace</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">infer_instance</span> </pre></div> </div> <p>In all the previous examples, we used the real numbers as the base field.
-
@@ -233,18 +234,18 @@ <em>nontrivially normed field</em>. These are fields that are equipped with areal-valued norm that is multiplicative and has the property that not every element has norm zero or one (equivalently, there is an element whose norm is bigger than one).</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="bp">𝕜</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">)</span> <span class="o">[</span><span class="n">NontriviallyNormedField</span> <span class="bp">𝕜</span><span class="o">]</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="bp">𝕜</span><span class="o">)</span> <span class="o">:</span> <span class="bp">‖</span><span class="n">x</span> <span class="bp">*</span> <span class="n">y</span><span class="bp">‖</span> <span class="bp">=</span> <span class="bp">‖</span><span class="n">x</span><span class="bp">‖</span> <span class="bp">*</span> <span class="bp">‖</span><span class="n">y</span><span class="bp">‖</span> <span class="o">:=</span> <span class="n">norm_mul</span> <span class="n">x</span> <span class="n">y</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">𝕜</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">NontriviallyNormedField</span><span class="w"> </span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">𝕜</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">‖</span><span class="n">x</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">y</span><span class="bp">‖</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">‖</span><span class="n">x</span><span class="bp">‖</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="bp">‖</span><span class="n">y</span><span class="bp">‖</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">norm_mul</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span> <span class="kd">example</span> <span class="o">(</span><span class="bp">𝕜</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">)</span> <span class="o">[</span><span class="n">NontriviallyNormedField</span> <span class="bp">𝕜</span><span class="o">]</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">x</span> <span class="o">:</span> <span class="bp">𝕜</span><span class="o">,</span> <span class="mi">1</span> <span class="bp"><</span> <span class="bp">‖</span><span class="n">x</span><span class="bp">‖</span> <span class="o">:=</span> <span class="n">NormedField.exists_one_lt_norm</span> <span class="bp">𝕜</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">𝕜</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">NontriviallyNormedField</span><span class="w"> </span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">𝕜</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">‖</span><span class="n">x</span><span class="bp">‖</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">NormedField.exists_one_lt_norm</span><span class="w"> </span><span class="n">𝕜</span> </pre></div> </div> <p>A finite-dimensional vector space over a nontrivially normed field is complete as long as the field itself is complete.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="bp">𝕜</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">)</span> <span class="o">[</span><span class="n">NontriviallyNormedField</span> <span class="bp">𝕜</span><span class="o">]</span> <span class="o">(</span><span class="n">E</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">)</span> <span class="o">[</span><span class="n">NormedAddCommGroup</span> <span class="n">E</span><span class="o">]</span> <span class="o">[</span><span class="n">NormedSpace</span> <span class="bp">𝕜</span> <span class="n">E</span><span class="o">]</span> <span class="o">[</span><span class="n">CompleteSpace</span> <span class="bp">𝕜</span><span class="o">]</span> <span class="o">[</span><span class="n">FiniteDimensional</span> <span class="bp">𝕜</span> <span class="n">E</span><span class="o">]</span> <span class="o">:</span> <span class="n">CompleteSpace</span> <span class="n">E</span> <span class="o">:=</span> <span class="n">FiniteDimensional.complete</span> <span class="bp">𝕜</span> <span class="n">E</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">𝕜</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">NontriviallyNormedField</span><span class="w"> </span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">E</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">NormedAddCommGroup</span><span class="w"> </span><span class="n">E</span><span class="o">]</span> <span class="w"> </span><span class="o">[</span><span class="n">NormedSpace</span><span class="w"> </span><span class="n">𝕜</span><span class="w"> </span><span class="n">E</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">CompleteSpace</span><span class="w"> </span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">FiniteDimensional</span><span class="w"> </span><span class="n">𝕜</span><span class="w"> </span><span class="n">E</span><span class="o">]</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">CompleteSpace</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">FiniteDimensional.complete</span><span class="w"> </span><span class="n">𝕜</span><span class="w"> </span><span class="n">E</span> </pre></div> </div> </section>
-
@@ -259,34 +260,34 @@ a structure that that includes the function itself and the propertiesof being linear and continuous. Lean will insert a coercion so that a continuous linear map can be treated as a function.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="bp">𝕜</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NontriviallyNormedField</span> <span class="bp">𝕜</span><span class="o">]</span> <span class="o">{</span><span class="n">E</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NormedAddCommGroup</span> <span class="n">E</span><span class="o">]</span> <span class="o">[</span><span class="n">NormedSpace</span> <span class="bp">𝕜</span> <span class="n">E</span><span class="o">]</span> <span class="o">{</span><span class="n">F</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NormedAddCommGroup</span> <span class="n">F</span><span class="o">]</span> <span class="o">[</span><span class="n">NormedSpace</span> <span class="bp">𝕜</span> <span class="n">F</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">𝕜</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">NontriviallyNormedField</span><span class="w"> </span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">E</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">NormedAddCommGroup</span><span class="w"> </span><span class="n">E</span><span class="o">]</span> <span class="w"> </span><span class="o">[</span><span class="n">NormedSpace</span><span class="w"> </span><span class="n">𝕜</span><span class="w"> </span><span class="n">E</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">NormedAddCommGroup</span><span class="w"> </span><span class="n">F</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">NormedSpace</span><span class="w"> </span><span class="n">𝕜</span><span class="w"> </span><span class="n">F</span><span class="o">]</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="bp">𝕜</span><span class="o">]</span> <span class="n">E</span> <span class="o">:=</span> <span class="n">ContinuousLinearMap.id</span> <span class="bp">𝕜</span> <span class="n">E</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">ContinuousLinearMap.id</span><span class="w"> </span><span class="n">𝕜</span><span class="w"> </span><span class="n">E</span> <span class="kd">example</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="bp">𝕜</span><span class="o">]</span> <span class="n">F</span><span class="o">)</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span> <span class="n">F</span> <span class="o">:=</span> <span class="n">f</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">f</span> <span class="kd">example</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="bp">𝕜</span><span class="o">]</span> <span class="n">F</span><span class="o">)</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="n">f</span> <span class="o">:=</span> <span class="n">f.cont</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">f.cont</span> <span class="kd">example</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="bp">𝕜</span><span class="o">]</span> <span class="n">F</span><span class="o">)</span> <span class="o">(</span><span class="n">x</span> <span class="n">y</span> <span class="o">:</span> <span class="n">E</span><span class="o">)</span> <span class="o">:</span> <span class="n">f</span> <span class="o">(</span><span class="n">x</span> <span class="bp">+</span> <span class="n">y</span><span class="o">)</span> <span class="bp">=</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">+</span> <span class="n">f</span> <span class="n">y</span> <span class="o">:=</span> <span class="n">f.map_add</span> <span class="n">x</span> <span class="n">y</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">f.map_add</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">y</span> <span class="kd">example</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="bp">𝕜</span><span class="o">]</span> <span class="n">F</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="o">:</span> <span class="bp">𝕜</span><span class="o">)</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">E</span><span class="o">)</span> <span class="o">:</span> <span class="n">f</span> <span class="o">(</span><span class="n">a</span> <span class="bp">•</span> <span class="n">x</span><span class="o">)</span> <span class="bp">=</span> <span class="n">a</span> <span class="bp">•</span> <span class="n">f</span> <span class="n">x</span> <span class="o">:=</span> <span class="n">f.map_smul</span> <span class="n">a</span> <span class="n">x</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">𝕜</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">f.map_smul</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">x</span> </pre></div> </div> <p>Continuous linear maps have an operator norm that is characterized by the following properties.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="bp">𝕜</span><span class="o">]</span> <span class="n">F</span><span class="o">)</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="n">F</span><span class="o">)</span> <span class="kd">example</span> <span class="o">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">E</span><span class="o">)</span> <span class="o">:</span> <span class="bp">‖</span><span class="n">f</span> <span class="n">x</span><span class="bp">‖</span> <span class="bp">≤</span> <span class="bp">‖</span><span class="n">f</span><span class="bp">‖</span> <span class="bp">*</span> <span class="bp">‖</span><span class="n">x</span><span class="bp">‖</span> <span class="o">:=</span> <span class="n">f.le_opNorm</span> <span class="n">x</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">‖</span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="bp">‖</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="bp">‖</span><span class="n">f</span><span class="bp">‖</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="bp">‖</span><span class="n">x</span><span class="bp">‖</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">f.le_opNorm</span><span class="w"> </span><span class="n">x</span> <span class="kd">example</span> <span class="o">{</span><span class="n">M</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">hMp</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp">≤</span> <span class="n">M</span><span class="o">)</span> <span class="o">(</span><span class="n">hM</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span><span class="o">,</span> <span class="bp">‖</span><span class="n">f</span> <span class="n">x</span><span class="bp">‖</span> <span class="bp">≤</span> <span class="n">M</span> <span class="bp">*</span> <span class="bp">‖</span><span class="n">x</span><span class="bp">‖</span><span class="o">)</span> <span class="o">:</span> <span class="bp">‖</span><span class="n">f</span><span class="bp">‖</span> <span class="bp">≤</span> <span class="n">M</span> <span class="o">:=</span> <span class="n">f.opNorm_le_bound</span> <span class="n">hMp</span> <span class="n">hM</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">M</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hMp</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">M</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hM</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="bp">‖</span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="bp">‖</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="bp">‖</span><span class="n">x</span><span class="bp">‖</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">‖</span><span class="n">f</span><span class="bp">‖</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">M</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">f.opNorm_le_bound</span><span class="w"> </span><span class="n">hMp</span><span class="w"> </span><span class="n">hM</span> </pre></div> </div> <p>There is also a notion of bundled continuous linear <em>isomorphism</em>.
-
@@ -300,33 +301,33 @@ The main ingredient is Baire’s theorem<code class="docutils literal notranslate"><span class="pre">nonempty_interior_of_iUnion_of_closed</span></code>. (You proved a version of this in the topology chapter.) Minor ingredients include <code class="docutils literal notranslate"><span class="pre">continuous_linear_map.opNorm_le_of_shell</span></code>, <code class="docutils literal notranslate"><span class="pre">interior_subset</span></code> and <code class="docutils literal notranslate"><span class="pre">interior_iInter_subset</span></code> and <code class="docutils literal notranslate"><span class="pre">isClosed_le</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="bp">𝕜</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NontriviallyNormedField</span> <span class="bp">𝕜</span><span class="o">]</span> <span class="o">{</span><span class="n">E</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NormedAddCommGroup</span> <span class="n">E</span><span class="o">]</span> <span class="o">[</span><span class="n">NormedSpace</span> <span class="bp">𝕜</span> <span class="n">E</span><span class="o">]</span> <span class="o">{</span><span class="n">F</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NormedAddCommGroup</span> <span class="n">F</span><span class="o">]</span> <span class="o">[</span><span class="n">NormedSpace</span> <span class="bp">𝕜</span> <span class="n">F</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">𝕜</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">NontriviallyNormedField</span><span class="w"> </span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">E</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">NormedAddCommGroup</span><span class="w"> </span><span class="n">E</span><span class="o">]</span> <span class="w"> </span><span class="o">[</span><span class="n">NormedSpace</span><span class="w"> </span><span class="n">𝕜</span><span class="w"> </span><span class="n">E</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">NormedAddCommGroup</span><span class="w"> </span><span class="n">F</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">NormedSpace</span><span class="w"> </span><span class="n">𝕜</span><span class="w"> </span><span class="n">F</span><span class="o">]</span> <span class="kn">open</span> <span class="n">Metric</span> <span class="kn">open</span><span class="w"> </span><span class="n">Metric</span> <span class="kd">example</span> <span class="o">{</span><span class="n">ι</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">CompleteSpace</span> <span class="n">E</span><span class="o">]</span> <span class="o">{</span><span class="n">g</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">E</span> <span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="bp">𝕜</span><span class="o">]</span> <span class="n">F</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">C</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">i</span><span class="o">,</span> <span class="bp">‖</span><span class="n">g</span> <span class="n">i</span> <span class="n">x</span><span class="bp">‖</span> <span class="bp">≤</span> <span class="n">C</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">C'</span><span class="o">,</span> <span class="bp">∀</span> <span class="n">i</span><span class="o">,</span> <span class="bp">‖</span><span class="n">g</span> <span class="n">i</span><span class="bp">‖</span> <span class="bp">≤</span> <span class="n">C'</span> <span class="o">:=</span> <span class="kd">by</span> <span class="c1">-- sequence of subsets consisting of those `x : E` with norms `‖g i x‖` bounded by `n`</span> <span class="k">let</span> <span class="n">e</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">Set</span> <span class="n">E</span> <span class="o">:=</span> <span class="k">fun</span> <span class="n">n</span> <span class="bp">↦</span> <span class="bp">⋂</span> <span class="n">i</span> <span class="o">:</span> <span class="n">ι</span><span class="o">,</span> <span class="o">{</span> <span class="n">x</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">|</span> <span class="bp">‖</span><span class="n">g</span> <span class="n">i</span> <span class="n">x</span><span class="bp">‖</span> <span class="bp">≤</span> <span class="n">n</span> <span class="o">}</span> <span class="c1">-- each of these sets is closed</span> <span class="k">have</span> <span class="n">hc</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">,</span> <span class="n">IsClosed</span> <span class="o">(</span><span class="n">e</span> <span class="n">n</span><span class="o">)</span> <span class="gr">sorry</span> <span class="c1">-- the union is the entire space; this is where we use `h`</span> <span class="k">have</span> <span class="n">hU</span> <span class="o">:</span> <span class="o">(</span><span class="bp">⋃</span> <span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">,</span> <span class="n">e</span> <span class="n">n</span><span class="o">)</span> <span class="bp">=</span> <span class="n">univ</span> <span class="gr">sorry</span> <span class="c">/-</span><span class="cm"> apply the Baire category theorem to conclude that for some `m : ℕ`,</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">ι</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">CompleteSpace</span><span class="w"> </span><span class="n">E</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="n">F</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">C</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="bp">‖</span><span class="n">g</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="n">x</span><span class="bp">‖</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">C</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">C'</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="bp">‖</span><span class="n">g</span><span class="w"> </span><span class="n">i</span><span class="bp">‖</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">C'</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span> <span class="w"> </span><span class="c1">-- sequence of subsets consisting of those `x : E` with norms `‖g i x‖` bounded by `n`</span> <span class="w"> </span><span class="k">let</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="bp">⋂</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="o">,</span><span class="w"> </span><span class="o">{</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">|</span><span class="w"> </span><span class="bp">‖</span><span class="n">g</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="n">x</span><span class="bp">‖</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">}</span> <span class="w"> </span><span class="c1">-- each of these sets is closed</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">hc</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">,</span><span class="w"> </span><span class="n">IsClosed</span><span class="w"> </span><span class="o">(</span><span class="n">e</span><span class="w"> </span><span class="n">n</span><span class="o">)</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="c1">-- the union is the entire space; this is where we use `h`</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">hU</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">⋃</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">,</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">univ</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="c">/-</span><span class="cm"> apply the Baire category theorem to conclude that for some `m : ℕ`,</span> <span class="cm"> `e m` contains some `x` -/</span> <span class="n">obtain</span> <span class="o">⟨</span><span class="n">m</span><span class="o">,</span> <span class="n">x</span><span class="o">,</span> <span class="n">hx</span><span class="o">⟩</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">m</span><span class="o">,</span> <span class="bp">∃</span> <span class="n">x</span><span class="o">,</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">interior</span> <span class="o">(</span><span class="n">e</span> <span class="n">m</span><span class="o">)</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">obtain</span> <span class="o">⟨</span><span class="n">ε</span><span class="o">,</span> <span class="n">ε_pos</span><span class="o">,</span> <span class="n">hε</span><span class="o">⟩</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">ε</span> <span class="bp">></span> <span class="mi">0</span><span class="o">,</span> <span class="n">ball</span> <span class="n">x</span> <span class="n">ε</span> <span class="bp">⊆</span> <span class="n">interior</span> <span class="o">(</span><span class="n">e</span> <span class="n">m</span><span class="o">)</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">obtain</span> <span class="o">⟨</span><span class="n">k</span><span class="o">,</span> <span class="n">hk</span><span class="o">⟩</span> <span class="o">:</span> <span class="bp">∃</span> <span class="n">k</span> <span class="o">:</span> <span class="bp">𝕜</span><span class="o">,</span> <span class="mi">1</span> <span class="bp"><</span> <span class="bp">‖</span><span class="n">k</span><span class="bp">‖</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="c1">-- show all elements in the ball have norm bounded by `m` after applying any `g i`</span> <span class="k">have</span> <span class="n">real_norm_le</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">z</span> <span class="bp">∈</span> <span class="n">ball</span> <span class="n">x</span> <span class="n">ε</span><span class="o">,</span> <span class="bp">∀</span> <span class="o">(</span><span class="n">i</span> <span class="o">:</span> <span class="n">ι</span><span class="o">),</span> <span class="bp">‖</span><span class="n">g</span> <span class="n">i</span> <span class="n">z</span><span class="bp">‖</span> <span class="bp">≤</span> <span class="n">m</span> <span class="gr">sorry</span> <span class="k">have</span> <span class="n">εk_pos</span> <span class="o">:</span> <span class="mi">0</span> <span class="bp"><</span> <span class="n">ε</span> <span class="bp">/</span> <span class="bp">‖</span><span class="n">k</span><span class="bp">‖</span> <span class="o">:=</span> <span class="gr">sorry</span> <span class="n">refine</span> <span class="o">⟨(</span><span class="n">m</span> <span class="bp">+</span> <span class="n">m</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="bp">/</span> <span class="o">(</span><span class="n">ε</span> <span class="bp">/</span> <span class="bp">‖</span><span class="n">k</span><span class="bp">‖</span><span class="o">),</span> <span class="k">fun</span> <span class="n">i</span> <span class="bp">↦</span> <span class="n">ContinuousLinearMap.opNorm_le_of_shell</span> <span class="n">ε_pos</span> <span class="bp">?</span><span class="n">_</span> <span class="n">hk</span> <span class="bp">?</span><span class="n">_</span><span class="o">⟩</span> <span class="gr">sorry</span> <span class="gr">sorry</span> <span class="w"> </span><span class="n">obtain</span><span class="w"> </span><span class="o">⟨</span><span class="n">m</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">hx</span><span class="o">⟩</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">m</span><span class="o">,</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">interior</span><span class="w"> </span><span class="o">(</span><span class="n">e</span><span class="w"> </span><span class="n">m</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">obtain</span><span class="w"> </span><span class="o">⟨</span><span class="n">ε</span><span class="o">,</span><span class="w"> </span><span class="n">ε_pos</span><span class="o">,</span><span class="w"> </span><span class="n">hε</span><span class="o">⟩</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="n">ball</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">interior</span><span class="w"> </span><span class="o">(</span><span class="n">e</span><span class="w"> </span><span class="n">m</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">obtain</span><span class="w"> </span><span class="o">⟨</span><span class="n">k</span><span class="o">,</span><span class="w"> </span><span class="n">hk</span><span class="o">⟩</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">𝕜</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="bp">‖</span><span class="n">k</span><span class="bp">‖</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="c1">-- show all elements in the ball have norm bounded by `m` after applying any `g i`</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">real_norm_le</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">ball</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="n">ε</span><span class="o">,</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="o">(</span><span class="n">i</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="o">),</span><span class="w"> </span><span class="bp">‖</span><span class="n">g</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="n">z</span><span class="bp">‖</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">m</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="k">have</span><span class="w"> </span><span class="n">εk_pos</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">ε</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="bp">‖</span><span class="n">k</span><span class="bp">‖</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="n">refine</span><span class="w"> </span><span class="o">⟨(</span><span class="n">m</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="o">(</span><span class="n">ε</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="bp">‖</span><span class="n">k</span><span class="bp">‖</span><span class="o">),</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">ContinuousLinearMap.opNorm_le_of_shell</span><span class="w"> </span><span class="n">ε_pos</span><span class="w"> </span><span class="bp">?</span><span class="n">_</span><span class="w"> </span><span class="n">hk</span><span class="w"> </span><span class="bp">?</span><span class="n">_</span><span class="o">⟩</span> <span class="w"> </span><span class="gr">sorry</span> <span class="w"> </span><span class="gr">sorry</span> </pre></div> </div> </section>
-
@@ -338,23 +339,23 @@ whose definitions are shown below.Opening the <code class="docutils literal notranslate"><span class="pre">asymptotics</span></code> locale allows us to use the corresponding notation. Here we will only use little o to define differentiability.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">Asymptotics</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">Asymptotics</span> <span class="kd">example</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">{</span><span class="n">E</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NormedGroup</span> <span class="n">E</span><span class="o">]</span> <span class="o">{</span><span class="n">F</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NormedGroup</span> <span class="n">F</span><span class="o">]</span> <span class="o">(</span><span class="n">c</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">l</span> <span class="o">:</span> <span class="n">Filter</span> <span class="n">α</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">E</span><span class="o">)</span> <span class="o">(</span><span class="n">g</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">F</span><span class="o">)</span> <span class="o">:</span> <span class="n">IsBigOWith</span> <span class="n">c</span> <span class="n">l</span> <span class="n">f</span> <span class="n">g</span> <span class="bp">↔</span> <span class="bp">∀ᶠ</span> <span class="n">x</span> <span class="k">in</span> <span class="n">l</span><span class="o">,</span> <span class="bp">‖</span><span class="n">f</span> <span class="n">x</span><span class="bp">‖</span> <span class="bp">≤</span> <span class="n">c</span> <span class="bp">*</span> <span class="bp">‖</span><span class="n">g</span> <span class="n">x</span><span class="bp">‖</span> <span class="o">:=</span> <span class="n">isBigOWith_iff</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">E</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">NormedGroup</span><span class="w"> </span><span class="n">E</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">NormedGroup</span><span class="w"> </span><span class="n">F</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="n">l</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">E</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IsBigOWith</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="n">l</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">l</span><span class="o">,</span><span class="w"> </span><span class="bp">‖</span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="bp">‖</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="bp">‖</span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="bp">‖</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">isBigOWith_iff</span> <span class="kd">example</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">{</span><span class="n">E</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NormedGroup</span> <span class="n">E</span><span class="o">]</span> <span class="o">{</span><span class="n">F</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NormedGroup</span> <span class="n">F</span><span class="o">]</span> <span class="o">(</span><span class="n">l</span> <span class="o">:</span> <span class="n">Filter</span> <span class="n">α</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">E</span><span class="o">)</span> <span class="o">(</span><span class="n">g</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">F</span><span class="o">)</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">=</span><span class="n">O</span><span class="o">[</span><span class="n">l</span><span class="o">]</span> <span class="n">g</span> <span class="bp">↔</span> <span class="bp">∃</span> <span class="n">C</span><span class="o">,</span> <span class="n">IsBigOWith</span> <span class="n">C</span> <span class="n">l</span> <span class="n">f</span> <span class="n">g</span> <span class="o">:=</span> <span class="n">isBigO_iff_isBigOWith</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">E</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">NormedGroup</span><span class="w"> </span><span class="n">E</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">NormedGroup</span><span class="w"> </span><span class="n">F</span><span class="o">]</span> <span class="w"> </span><span class="o">(</span><span class="n">l</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">E</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">=</span><span class="n">O</span><span class="o">[</span><span class="n">l</span><span class="o">]</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∃</span><span class="w"> </span><span class="n">C</span><span class="o">,</span><span class="w"> </span><span class="n">IsBigOWith</span><span class="w"> </span><span class="n">C</span><span class="w"> </span><span class="n">l</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">isBigO_iff_isBigOWith</span> <span class="kd">example</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">{</span><span class="n">E</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NormedGroup</span> <span class="n">E</span><span class="o">]</span> <span class="o">{</span><span class="n">F</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NormedGroup</span> <span class="n">F</span><span class="o">]</span> <span class="o">(</span><span class="n">l</span> <span class="o">:</span> <span class="n">Filter</span> <span class="n">α</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">E</span><span class="o">)</span> <span class="o">(</span><span class="n">g</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">F</span><span class="o">)</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">=</span><span class="n">o</span><span class="o">[</span><span class="n">l</span><span class="o">]</span> <span class="n">g</span> <span class="bp">↔</span> <span class="bp">∀</span> <span class="n">C</span> <span class="bp">></span> <span class="mi">0</span><span class="o">,</span> <span class="n">IsBigOWith</span> <span class="n">C</span> <span class="n">l</span> <span class="n">f</span> <span class="n">g</span> <span class="o">:=</span> <span class="n">isLittleO_iff_forall_isBigOWith</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">E</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">NormedGroup</span><span class="w"> </span><span class="n">E</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">NormedGroup</span><span class="w"> </span><span class="n">F</span><span class="o">]</span> <span class="w"> </span><span class="o">(</span><span class="n">l</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">E</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">=</span><span class="n">o</span><span class="o">[</span><span class="n">l</span><span class="o">]</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">C</span><span class="w"> </span><span class="bp">></span><span class="w"> </span><span class="mi">0</span><span class="o">,</span><span class="w"> </span><span class="n">IsBigOWith</span><span class="w"> </span><span class="n">C</span><span class="w"> </span><span class="n">l</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">isLittleO_iff_forall_isBigOWith</span> <span class="kd">example</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">{</span><span class="n">E</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NormedAddCommGroup</span> <span class="n">E</span><span class="o">]</span> <span class="o">(</span><span class="n">l</span> <span class="o">:</span> <span class="n">Filter</span> <span class="n">α</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="n">g</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">E</span><span class="o">)</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">~</span><span class="o">[</span><span class="n">l</span><span class="o">]</span> <span class="n">g</span> <span class="bp">↔</span> <span class="o">(</span><span class="n">f</span> <span class="bp">-</span> <span class="n">g</span><span class="o">)</span> <span class="bp">=</span><span class="n">o</span><span class="o">[</span><span class="n">l</span><span class="o">]</span> <span class="n">g</span> <span class="o">:=</span> <span class="n">Iff.rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">E</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">NormedAddCommGroup</span><span class="w"> </span><span class="n">E</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">l</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">E</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">~</span><span class="o">[</span><span class="n">l</span><span class="o">]</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">g</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="n">o</span><span class="o">[</span><span class="n">l</span><span class="o">]</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Iff.rfl</span> </pre></div> </div> </section>
-
@@ -365,17 +366,17 @@ In analogy the elementary one-dimensional,Mathlib defines a predicate <code class="docutils literal notranslate"><span class="pre">HasFDerivAt</span></code> and a function <code class="docutils literal notranslate"><span class="pre">fderiv</span></code>. Here the letter “f” stands for <em>Fréchet</em>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">Topology</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">Topology</span> <span class="kd">variable</span> <span class="o">{</span><span class="bp">𝕜</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NontriviallyNormedField</span> <span class="bp">𝕜</span><span class="o">]</span> <span class="o">{</span><span class="n">E</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NormedAddCommGroup</span> <span class="n">E</span><span class="o">]</span> <span class="o">[</span><span class="n">NormedSpace</span> <span class="bp">𝕜</span> <span class="n">E</span><span class="o">]</span> <span class="o">{</span><span class="n">F</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NormedAddCommGroup</span> <span class="n">F</span><span class="o">]</span> <span class="o">[</span><span class="n">NormedSpace</span> <span class="bp">𝕜</span> <span class="n">F</span><span class="o">]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">𝕜</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">NontriviallyNormedField</span><span class="w"> </span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">E</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">NormedAddCommGroup</span><span class="w"> </span><span class="n">E</span><span class="o">]</span> <span class="w"> </span><span class="o">[</span><span class="n">NormedSpace</span><span class="w"> </span><span class="n">𝕜</span><span class="w"> </span><span class="n">E</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">NormedAddCommGroup</span><span class="w"> </span><span class="n">F</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">NormedSpace</span><span class="w"> </span><span class="n">𝕜</span><span class="w"> </span><span class="n">F</span><span class="o">]</span> <span class="kd">example</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span> <span class="n">F</span><span class="o">)</span> <span class="o">(</span><span class="n">f'</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="bp">𝕜</span><span class="o">]</span> <span class="n">F</span><span class="o">)</span> <span class="o">(</span><span class="n">x₀</span> <span class="o">:</span> <span class="n">E</span><span class="o">)</span> <span class="o">:</span> <span class="n">HasFDerivAt</span> <span class="n">f</span> <span class="n">f'</span> <span class="n">x₀</span> <span class="bp">↔</span> <span class="o">(</span><span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">f</span> <span class="n">x</span> <span class="bp">-</span> <span class="n">f</span> <span class="n">x₀</span> <span class="bp">-</span> <span class="n">f'</span> <span class="o">(</span><span class="n">x</span> <span class="bp">-</span> <span class="n">x₀</span><span class="o">))</span> <span class="bp">=</span><span class="n">o</span><span class="o">[</span><span class="bp">𝓝</span> <span class="n">x₀</span><span class="o">]</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">x</span> <span class="bp">-</span> <span class="n">x₀</span> <span class="o">:=</span> <span class="n">hasFDerivAtFilter_iff_isLittleO</span> <span class="bp">..</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">x₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">HasFDerivAt</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">f'</span><span class="w"> </span><span class="n">x₀</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x₀</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">f'</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">x₀</span><span class="o">))</span><span class="w"> </span><span class="bp">=</span><span class="n">o</span><span class="o">[</span><span class="n">𝓝</span><span class="w"> </span><span class="n">x₀</span><span class="o">]</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">x₀</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">hasFDerivAtFilter_iff_isLittleO</span><span class="w"> </span><span class="bp">..</span> <span class="kd">example</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span> <span class="n">F</span><span class="o">)</span> <span class="o">(</span><span class="n">f'</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="bp">𝕜</span><span class="o">]</span> <span class="n">F</span><span class="o">)</span> <span class="o">(</span><span class="n">x₀</span> <span class="o">:</span> <span class="n">E</span><span class="o">)</span> <span class="o">(</span><span class="n">hff'</span> <span class="o">:</span> <span class="n">HasFDerivAt</span> <span class="n">f</span> <span class="n">f'</span> <span class="n">x₀</span><span class="o">)</span> <span class="o">:</span> <span class="n">fderiv</span> <span class="bp">𝕜</span> <span class="n">f</span> <span class="n">x₀</span> <span class="bp">=</span> <span class="n">f'</span> <span class="o">:=</span> <span class="n">hff'.fderiv</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">x₀</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hff'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">HasFDerivAt</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">f'</span><span class="w"> </span><span class="n">x₀</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">fderiv</span><span class="w"> </span><span class="n">𝕜</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x₀</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f'</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">hff'.fderiv</span> </pre></div> </div> <p>We also have iterated derivatives that take values in the type of multilinear maps
-
@@ -385,14 +386,14 @@ The type <code class="docutils literal notranslate"><span class="pre">WithTop</span> <span class="pre">ℕ</span></code> is <code class="docutils literal notranslate"><span class="pre">ℕ</span></code> with an additional element <code class="docutils literal notranslate"><span class="pre">⊤</span></code> thatis bigger than every natural number. So <span class="math notranslate nohighlight">\(\mathcal{C}^\infty\)</span> functions are functions <code class="docutils literal notranslate"><span class="pre">f</span></code> that satisfy <code class="docutils literal notranslate"><span class="pre">ContDiff</span> <span class="pre">𝕜</span> <span class="pre">⊤</span> <span class="pre">f</span></code>.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span> <span class="n">F</span><span class="o">)</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span> <span class="n">E</span><span class="o">[</span><span class="bp">×</span><span class="n">n</span><span class="o">]</span><span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="bp">𝕜</span><span class="o">]</span> <span class="n">F</span> <span class="o">:=</span> <span class="n">iteratedFDeriv</span> <span class="bp">𝕜</span> <span class="n">n</span> <span class="n">f</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">E</span><span class="o">[</span><span class="bp">×</span><span class="n">n</span><span class="o">]</span><span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">iteratedFDeriv</span><span class="w"> </span><span class="n">𝕜</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">f</span> <span class="kd">example</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">WithTop</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span> <span class="n">F</span><span class="o">}</span> <span class="o">:</span> <span class="n">ContDiff</span> <span class="bp">𝕜</span> <span class="n">n</span> <span class="n">f</span> <span class="bp">↔</span> <span class="o">(</span><span class="bp">∀</span> <span class="n">m</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">,</span> <span class="o">(</span><span class="n">m</span> <span class="o">:</span> <span class="n">WithTop</span> <span class="n">ℕ</span><span class="o">)</span> <span class="bp">≤</span> <span class="n">n</span> <span class="bp">→</span> <span class="n">Continuous</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">iteratedFDeriv</span> <span class="bp">𝕜</span> <span class="n">m</span> <span class="n">f</span> <span class="n">x</span><span class="o">)</span> <span class="bp">∧</span> <span class="bp">∀</span> <span class="n">m</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">,</span> <span class="o">(</span><span class="n">m</span> <span class="o">:</span> <span class="n">WithTop</span> <span class="n">ℕ</span><span class="o">)</span> <span class="bp"><</span> <span class="n">n</span> <span class="bp">→</span> <span class="n">Differentiable</span> <span class="bp">𝕜</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="n">iteratedFDeriv</span> <span class="bp">𝕜</span> <span class="n">m</span> <span class="n">f</span> <span class="n">x</span> <span class="o">:=</span> <span class="n">contDiff_iff_continuous_differentiable</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">WithTop</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">F</span><span class="o">}</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">ContDiff</span><span class="w"> </span><span class="n">𝕜</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">↔</span> <span class="w"> </span><span class="o">(</span><span class="bp">∀</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">,</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">WithTop</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">iteratedFDeriv</span><span class="w"> </span><span class="n">𝕜</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">∧</span> <span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">,</span><span class="w"> </span><span class="o">(</span><span class="n">m</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">WithTop</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="bp"><</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Differentiable</span><span class="w"> </span><span class="n">𝕜</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">iteratedFDeriv</span><span class="w"> </span><span class="n">𝕜</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">contDiff_iff_continuous_differentiable</span> </pre></div> </div> <p>There is a stricter notion of differentiability called
-
@@ -401,10 +402,10 @@ of the inverse function theorem and the statement of the implicit functiontheorem, both of which are in Mathlib. Over <code class="docutils literal notranslate"><span class="pre">ℝ</span></code> or <code class="docutils literal notranslate"><span class="pre">ℂ</span></code>, continuously differentiable functions are strictly differentiable.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="bp">𝕂</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">RCLike</span> <span class="bp">𝕂</span><span class="o">]</span> <span class="o">{</span><span class="n">E</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NormedAddCommGroup</span> <span class="n">E</span><span class="o">]</span> <span class="o">[</span><span class="n">NormedSpace</span> <span class="bp">𝕂</span> <span class="n">E</span><span class="o">]</span> <span class="o">{</span><span class="n">F</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NormedAddCommGroup</span> <span class="n">F</span><span class="o">]</span> <span class="o">[</span><span class="n">NormedSpace</span> <span class="bp">𝕂</span> <span class="n">F</span><span class="o">]</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span> <span class="n">F</span><span class="o">}</span> <span class="o">{</span><span class="n">x</span> <span class="o">:</span> <span class="n">E</span><span class="o">}</span> <span class="o">{</span><span class="n">n</span> <span class="o">:</span> <span class="n">WithTop</span> <span class="n">ℕ</span><span class="o">}</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">ContDiffAt</span> <span class="bp">𝕂</span> <span class="n">n</span> <span class="n">f</span> <span class="n">x</span><span class="o">)</span> <span class="o">(</span><span class="n">hn</span> <span class="o">:</span> <span class="mi">1</span> <span class="bp">≤</span> <span class="n">n</span><span class="o">)</span> <span class="o">:</span> <span class="n">HasStrictFDerivAt</span> <span class="n">f</span> <span class="o">(</span><span class="n">fderiv</span> <span class="bp">𝕂</span> <span class="n">f</span> <span class="n">x</span><span class="o">)</span> <span class="n">x</span> <span class="o">:=</span> <span class="n">hf.hasStrictFDerivAt</span> <span class="n">hn</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">𝕂</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">RCLike</span><span class="w"> </span><span class="n">𝕂</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">E</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">NormedAddCommGroup</span><span class="w"> </span><span class="n">E</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">NormedSpace</span><span class="w"> </span><span class="n">𝕂</span><span class="w"> </span><span class="n">E</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="w"> </span><span class="o">[</span><span class="n">NormedAddCommGroup</span><span class="w"> </span><span class="n">F</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">NormedSpace</span><span class="w"> </span><span class="n">𝕂</span><span class="w"> </span><span class="n">F</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">F</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">WithTop</span><span class="w"> </span><span class="n">ℕ</span><span class="o">}</span> <span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ContDiffAt</span><span class="w"> </span><span class="n">𝕂</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hn</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">HasStrictFDerivAt</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">fderiv</span><span class="w"> </span><span class="n">𝕂</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">hf.hasStrictFDerivAt</span><span class="w"> </span><span class="n">hn</span> </pre></div> </div> <p>The local inverse theorem is stated using an operation that produces an
-
@@ -414,26 +415,26 @@ point <code class="docutils literal notranslate"><span class="pre">a</span></code> and that its derivative is an isomorphism.</p><p>The first example below gets this local inverse. The next one states that it is indeed a local inverse from the left and from the right, and that it is strictly differentiable.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span> <span class="n">LocalInverse</span> <span class="kd">variable</span> <span class="o">[</span><span class="n">CompleteSpace</span> <span class="n">E</span><span class="o">]</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span> <span class="n">F</span><span class="o">}</span> <span class="o">{</span><span class="n">f'</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">≃</span><span class="n">L</span><span class="o">[</span><span class="bp">𝕜</span><span class="o">]</span> <span class="n">F</span><span class="o">}</span> <span class="o">{</span><span class="n">a</span> <span class="o">:</span> <span class="n">E</span><span class="o">}</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span><span class="w"> </span><span class="n">LocalInverse</span> <span class="kd">variable</span><span class="w"> </span><span class="o">[</span><span class="n">CompleteSpace</span><span class="w"> </span><span class="n">E</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">F</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">f'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">≃</span><span class="n">L</span><span class="o">[</span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="n">F</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="o">}</span> <span class="kd">example</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">HasStrictFDerivAt</span> <span class="n">f</span> <span class="o">(</span><span class="n">f'</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="bp">𝕜</span><span class="o">]</span> <span class="n">F</span><span class="o">)</span> <span class="n">a</span><span class="o">)</span> <span class="o">:</span> <span class="n">F</span> <span class="bp">→</span> <span class="n">E</span> <span class="o">:=</span> <span class="n">HasStrictFDerivAt.localInverse</span> <span class="n">f</span> <span class="n">f'</span> <span class="n">a</span> <span class="n">hf</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">HasStrictFDerivAt</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">f'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">HasStrictFDerivAt.localInverse</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">f'</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">hf</span> <span class="kd">example</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">HasStrictFDerivAt</span> <span class="n">f</span> <span class="o">(</span><span class="n">f'</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="bp">𝕜</span><span class="o">]</span> <span class="n">F</span><span class="o">)</span> <span class="n">a</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∀ᶠ</span> <span class="n">x</span> <span class="k">in</span> <span class="bp">𝓝</span> <span class="n">a</span><span class="o">,</span> <span class="n">hf.localInverse</span> <span class="n">f</span> <span class="n">f'</span> <span class="n">a</span> <span class="o">(</span><span class="n">f</span> <span class="n">x</span><span class="o">)</span> <span class="bp">=</span> <span class="n">x</span> <span class="o">:=</span> <span class="n">hf.eventually_left_inverse</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">HasStrictFDerivAt</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">f'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">𝓝</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">hf.localInverse</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">f'</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">hf.eventually_left_inverse</span> <span class="kd">example</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">HasStrictFDerivAt</span> <span class="n">f</span> <span class="o">(</span><span class="n">f'</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="bp">𝕜</span><span class="o">]</span> <span class="n">F</span><span class="o">)</span> <span class="n">a</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∀ᶠ</span> <span class="n">x</span> <span class="k">in</span> <span class="bp">𝓝</span> <span class="o">(</span><span class="n">f</span> <span class="n">a</span><span class="o">),</span> <span class="n">f</span> <span class="o">(</span><span class="n">hf.localInverse</span> <span class="n">f</span> <span class="n">f'</span> <span class="n">a</span> <span class="n">x</span><span class="o">)</span> <span class="bp">=</span> <span class="n">x</span> <span class="o">:=</span> <span class="n">hf.eventually_right_inverse</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">HasStrictFDerivAt</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">f'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">𝓝</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="o">),</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">hf.localInverse</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">f'</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">hf.eventually_right_inverse</span> <span class="kd">example</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span> <span class="n">F</span><span class="o">}</span> <span class="o">{</span><span class="n">f'</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">≃</span><span class="n">L</span><span class="o">[</span><span class="bp">𝕜</span><span class="o">]</span> <span class="n">F</span><span class="o">}</span> <span class="o">{</span><span class="n">a</span> <span class="o">:</span> <span class="n">E</span><span class="o">}</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">HasStrictFDerivAt</span> <span class="n">f</span> <span class="o">(</span><span class="n">f'</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="bp">𝕜</span><span class="o">]</span> <span class="n">F</span><span class="o">)</span> <span class="n">a</span><span class="o">)</span> <span class="o">:</span> <span class="n">HasStrictFDerivAt</span> <span class="o">(</span><span class="n">HasStrictFDerivAt.localInverse</span> <span class="n">f</span> <span class="n">f'</span> <span class="n">a</span> <span class="n">hf</span><span class="o">)</span> <span class="o">(</span><span class="n">f'.symm</span> <span class="o">:</span> <span class="n">F</span> <span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="bp">𝕜</span><span class="o">]</span> <span class="n">E</span><span class="o">)</span> <span class="o">(</span><span class="n">f</span> <span class="n">a</span><span class="o">)</span> <span class="o">:=</span> <span class="n">HasStrictFDerivAt.to_localInverse</span> <span class="n">hf</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">F</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">f'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">≃</span><span class="n">L</span><span class="o">[</span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="n">F</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="o">}</span> <span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">HasStrictFDerivAt</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">f'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">HasStrictFDerivAt</span><span class="w"> </span><span class="o">(</span><span class="n">HasStrictFDerivAt.localInverse</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">f'</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">hf</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f'.symm</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="n">E</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">HasStrictFDerivAt.to_localInverse</span><span class="w"> </span><span class="n">hf</span> <span class="kd">end</span> <span class="n">LocalInverse</span> <span class="kd">end</span><span class="w"> </span><span class="n">LocalInverse</span> </pre></div> </div> <p>This has been only a quick tour of the differential calculus in Mathlib.
-
-
-
@@ -1,3 +1,5 @@<!DOCTYPE html> <html class="writer-html5" lang="en" data-content_root="./"> <head>
-
@@ -6,18 +8,17 @@<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>12. Integration and Measure Theory — Mathematics in Lean 0.1 documentation</title> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=80d5e7a1" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=86f27845" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" /> <link rel="stylesheet" type="text/css" href="_static/css/custom.css?v=0731ccc3" /> <link rel="shortcut icon" href="_static/favicon.ico"/> <script src="_static/jquery.js?v=8dae8fb0"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=888ff710"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> <script src="_static/jquery.js?v=5d32c60e"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=9bcbadda"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> <script src="_static/js/theme.js"></script> <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" />
-
@@ -97,16 +98,16 @@ <section id="elementary-integration"><span id="index-1"></span><span id="id2"></span><h2><span class="section-number">12.1. </span>Elementary Integration<a class="headerlink" href="#elementary-integration" title="Link to this heading"></a></h2> <p>We first focus on integration of functions on finite intervals in <code class="docutils literal notranslate"><span class="pre">ℝ</span></code>. We can integrate elementary functions.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">MeasureTheory</span> <span class="n">intervalIntegral</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">MeasureTheory</span><span class="w"> </span><span class="n">intervalIntegral</span> <span class="kn">open</span> <span class="n">Interval</span> <span class="kn">open</span><span class="w"> </span><span class="n">Interval</span> <span class="c1">-- this introduces the notation `[[a, b]]` for the segment from `min a b` to `max a b`</span> <span class="kd">example</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="bp">∫</span> <span class="n">x</span> <span class="k">in</span> <span class="n">a..b</span><span class="o">,</span> <span class="n">x</span><span class="o">)</span> <span class="bp">=</span> <span class="o">(</span><span class="n">b</span> <span class="bp">^</span> <span class="mi">2</span> <span class="bp">-</span> <span class="n">a</span> <span class="bp">^</span> <span class="mi">2</span><span class="o">)</span> <span class="bp">/</span> <span class="mi">2</span> <span class="o">:=</span> <span class="n">integral_id</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">∫</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">a</span><span class="bp">..</span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">^</span><span class="w"> </span><span class="mi">2</span><span class="o">)</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">integral_id</span> <span class="kd">example</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="o">(</span><span class="mi">0</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="bp">∉</span> <span class="o">[[</span><span class="n">a</span><span class="o">,</span> <span class="n">b</span><span class="o">]])</span> <span class="o">:</span> <span class="o">(</span><span class="bp">∫</span> <span class="n">x</span> <span class="k">in</span> <span class="n">a..b</span><span class="o">,</span> <span class="mi">1</span> <span class="bp">/</span> <span class="n">x</span><span class="o">)</span> <span class="bp">=</span> <span class="n">Real.log</span> <span class="o">(</span><span class="n">b</span> <span class="bp">/</span> <span class="n">a</span><span class="o">)</span> <span class="o">:=</span> <span class="n">integral_one_div</span> <span class="n">h</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="mi">0</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="bp">∉</span><span class="w"> </span><span class="o">[[</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">b</span><span class="o">]])</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">∫</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">a</span><span class="bp">..</span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">Real.log</span><span class="w"> </span><span class="o">(</span><span class="n">b</span><span class="w"> </span><span class="bp">/</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">integral_one_div</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>The fundamental theorem of calculus relates integration and differentiation.
-
@@ -115,20 +116,20 @@ says that integration provides an inverse to differentiation and the second onespecifies how to compute integrals of derivatives. (These two parts are very closely related, but their optimal versions, which are not shown here, are not equivalent.)</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">Continuous</span> <span class="n">f</span><span class="o">)</span> <span class="o">(</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">deriv</span> <span class="o">(</span><span class="k">fun</span> <span class="n">u</span> <span class="bp">↦</span> <span class="bp">∫</span> <span class="n">x</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="k">in</span> <span class="n">a..u</span><span class="o">,</span> <span class="n">f</span> <span class="n">x</span><span class="o">)</span> <span class="n">b</span> <span class="bp">=</span> <span class="n">f</span> <span class="n">b</span> <span class="o">:=</span> <span class="o">(</span><span class="n">integral_hasStrictDerivAt_right</span> <span class="o">(</span><span class="n">hf.intervalIntegrable</span> <span class="n">_</span> <span class="n">_</span><span class="o">)</span> <span class="o">(</span><span class="n">hf.stronglyMeasurableAtFilter</span> <span class="n">_</span> <span class="n">_</span><span class="o">)</span> <span class="n">hf.continuousAt</span><span class="o">)</span><span class="bp">.</span><span class="n">hasDerivAt.deriv</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Continuous</span><span class="w"> </span><span class="n">f</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">deriv</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">u</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="bp">∫</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">a</span><span class="bp">..</span><span class="n">u</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="o">(</span><span class="n">integral_hasStrictDerivAt_right</span><span class="w"> </span><span class="o">(</span><span class="n">hf.intervalIntegrable</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">_</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hf.stronglyMeasurableAtFilter</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="n">_</span><span class="o">)</span> <span class="w"> </span><span class="n">hf.continuousAt</span><span class="o">)</span><span class="bp">.</span><span class="n">hasDerivAt.deriv</span> <span class="kd">example</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">{</span><span class="n">a</span> <span class="n">b</span> <span class="o">:</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">{</span><span class="n">f'</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="bp">∈</span> <span class="o">[[</span><span class="n">a</span><span class="o">,</span> <span class="n">b</span><span class="o">]],</span> <span class="n">HasDerivAt</span> <span class="n">f</span> <span class="o">(</span><span class="n">f'</span> <span class="n">x</span><span class="o">)</span> <span class="n">x</span><span class="o">)</span> <span class="o">(</span><span class="n">h'</span> <span class="o">:</span> <span class="n">IntervalIntegrable</span> <span class="n">f'</span> <span class="n">volume</span> <span class="n">a</span> <span class="n">b</span><span class="o">)</span> <span class="o">:</span> <span class="o">(</span><span class="bp">∫</span> <span class="n">y</span> <span class="k">in</span> <span class="n">a..b</span><span class="o">,</span> <span class="n">f'</span> <span class="n">y</span><span class="o">)</span> <span class="bp">=</span> <span class="n">f</span> <span class="n">b</span> <span class="bp">-</span> <span class="n">f</span> <span class="n">a</span> <span class="o">:=</span> <span class="n">integral_eq_sub_of_hasDerivAt</span> <span class="n">h</span> <span class="n">h'</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">f'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="o">[[</span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">b</span><span class="o">]],</span><span class="w"> </span><span class="n">HasDerivAt</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">f'</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="n">x</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="n">h'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">IntervalIntegrable</span><span class="w"> </span><span class="n">f'</span><span class="w"> </span><span class="n">volume</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">∫</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">a</span><span class="bp">..</span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">f'</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">integral_eq_sub_of_hasDerivAt</span><span class="w"> </span><span class="n">h</span><span class="w"> </span><span class="n">h'</span> </pre></div> </div> <p>Convolution is also defined in Mathlib and its basic properties are proved.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">Convolution</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">Convolution</span> <span class="kd">example</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">g</span> <span class="o">:</span> <span class="n">ℝ</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">⋆</span> <span class="n">g</span> <span class="bp">=</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="bp">∫</span> <span class="n">t</span><span class="o">,</span> <span class="n">f</span> <span class="n">t</span> <span class="bp">*</span> <span class="n">g</span> <span class="o">(</span><span class="n">x</span> <span class="bp">-</span> <span class="n">t</span><span class="o">)</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⋆</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="bp">∫</span><span class="w"> </span><span class="n">t</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="bp">*</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> </pre></div> </div> </section>
-
@@ -149,28 +150,28 @@ Note that these axioms are redundant; if you <code class="docutils literal notranslate"><span class="pre">#print</span> <span class="pre">MeasurableSpace</span></code>,you will see the ones that Mathlib uses. As the examples below show, countability assumptions can be expressed using the <code class="docutils literal notranslate"><span class="pre">Encodable</span></code> type class.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">MeasurableSpace</span> <span class="n">α</span><span class="o">]</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">MeasurableSpace</span><span class="w"> </span><span class="n">α</span><span class="o">]</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">MeasurableSet</span> <span class="o">(</span><span class="bp">∅</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">α</span><span class="o">)</span> <span class="o">:=</span> <span class="n">MeasurableSet.empty</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MeasurableSet</span><span class="w"> </span><span class="o">(</span><span class="bp">∅</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">MeasurableSet.empty</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">MeasurableSet</span> <span class="o">(</span><span class="n">univ</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">α</span><span class="o">)</span> <span class="o">:=</span> <span class="n">MeasurableSet.univ</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MeasurableSet</span><span class="w"> </span><span class="o">(</span><span class="n">univ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">MeasurableSet.univ</span> <span class="kd">example</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">α</span><span class="o">}</span> <span class="o">(</span><span class="n">hs</span> <span class="o">:</span> <span class="n">MeasurableSet</span> <span class="n">s</span><span class="o">)</span> <span class="o">:</span> <span class="n">MeasurableSet</span> <span class="o">(</span><span class="n">s</span><span class="bp">ᶜ</span><span class="o">)</span> <span class="o">:=</span> <span class="n">hs.compl</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MeasurableSet</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MeasurableSet</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="bp">ᶜ</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">hs.compl</span> <span class="kd">example</span> <span class="o">:</span> <span class="n">Encodable</span> <span class="n">ℕ</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">infer_instance</span> <span class="kd">example</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Encodable</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">infer_instance</span> <span class="kd">example</span> <span class="o">(</span><span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span><span class="o">)</span> <span class="o">:</span> <span class="n">Encodable</span> <span class="o">(</span><span class="n">Fin</span> <span class="n">n</span><span class="o">)</span> <span class="o">:=</span> <span class="kd">by</span> <span class="n">infer_instance</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Encodable</span><span class="w"> </span><span class="o">(</span><span class="n">Fin</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">by</span><span class="w"> </span><span class="n">infer_instance</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">ι</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">Encodable</span> <span class="n">ι</span><span class="o">]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">ι</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">Encodable</span><span class="w"> </span><span class="n">ι</span><span class="o">]</span> <span class="kd">example</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">Set</span> <span class="n">α</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">b</span><span class="o">,</span> <span class="n">MeasurableSet</span> <span class="o">(</span><span class="n">f</span> <span class="n">b</span><span class="o">))</span> <span class="o">:</span> <span class="n">MeasurableSet</span> <span class="o">(</span><span class="bp">⋃</span> <span class="n">b</span><span class="o">,</span> <span class="n">f</span> <span class="n">b</span><span class="o">)</span> <span class="o">:=</span> <span class="n">MeasurableSet.iUnion</span> <span class="n">h</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">MeasurableSet</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">b</span><span class="o">))</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MeasurableSet</span><span class="w"> </span><span class="o">(</span><span class="bp">⋃</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">MeasurableSet.iUnion</span><span class="w"> </span><span class="n">h</span> <span class="kd">example</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">Set</span> <span class="n">α</span><span class="o">}</span> <span class="o">(</span><span class="n">h</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">b</span><span class="o">,</span> <span class="n">MeasurableSet</span> <span class="o">(</span><span class="n">f</span> <span class="n">b</span><span class="o">))</span> <span class="o">:</span> <span class="n">MeasurableSet</span> <span class="o">(</span><span class="bp">⋂</span> <span class="n">b</span><span class="o">,</span> <span class="n">f</span> <span class="n">b</span><span class="o">)</span> <span class="o">:=</span> <span class="n">MeasurableSet.iInter</span> <span class="n">h</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">h</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">MeasurableSet</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">b</span><span class="o">))</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MeasurableSet</span><span class="w"> </span><span class="o">(</span><span class="bp">⋂</span><span class="w"> </span><span class="n">b</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">b</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">MeasurableSet.iInter</span><span class="w"> </span><span class="n">h</span> </pre></div> </div> <p>Once a type is measurable, we can measure it. On paper, a measure on a set
-
@@ -184,18 +185,18 @@ So we extend the measure to any set <code class="docutils literal notranslate"><span class="pre">s</span></code>as the infimum of measures of measurable sets containing <code class="docutils literal notranslate"><span class="pre">s</span></code>. Of course, many lemmas still require measurability assumptions, but not all.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">MeasureTheory</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">μ</span> <span class="o">:</span> <span class="n">Measure</span> <span class="n">α</span><span class="o">}</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">MeasureTheory</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">μ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Measure</span><span class="w"> </span><span class="n">α</span><span class="o">}</span> <span class="kd">example</span> <span class="o">(</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">α</span><span class="o">)</span> <span class="o">:</span> <span class="n">μ</span> <span class="n">s</span> <span class="bp">=</span> <span class="bp">⨅</span> <span class="o">(</span><span class="n">t</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">α</span><span class="o">)</span> <span class="o">(</span><span class="n">_</span> <span class="o">:</span> <span class="n">s</span> <span class="bp">⊆</span> <span class="n">t</span><span class="o">)</span> <span class="o">(</span><span class="n">_</span> <span class="o">:</span> <span class="n">MeasurableSet</span> <span class="n">t</span><span class="o">),</span> <span class="n">μ</span> <span class="n">t</span> <span class="o">:=</span> <span class="n">measure_eq_iInf</span> <span class="n">s</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">μ</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">⨅</span><span class="w"> </span><span class="o">(</span><span class="n">t</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">_</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">⊆</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">_</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MeasurableSet</span><span class="w"> </span><span class="n">t</span><span class="o">),</span><span class="w"> </span><span class="n">μ</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">measure_eq_iInf</span><span class="w"> </span><span class="n">s</span> <span class="kd">example</span> <span class="o">(</span><span class="n">s</span> <span class="o">:</span> <span class="n">ι</span> <span class="bp">→</span> <span class="n">Set</span> <span class="n">α</span><span class="o">)</span> <span class="o">:</span> <span class="n">μ</span> <span class="o">(</span><span class="bp">⋃</span> <span class="n">i</span><span class="o">,</span> <span class="n">s</span> <span class="n">i</span><span class="o">)</span> <span class="bp">≤</span> <span class="bp">∑'</span> <span class="n">i</span><span class="o">,</span> <span class="n">μ</span> <span class="o">(</span><span class="n">s</span> <span class="n">i</span><span class="o">)</span> <span class="o">:=</span> <span class="n">measure_iUnion_le</span> <span class="n">s</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ι</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">μ</span><span class="w"> </span><span class="o">(</span><span class="bp">⋃</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="bp">∑'</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">μ</span><span class="w"> </span><span class="o">(</span><span class="n">s</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">measure_iUnion_le</span><span class="w"> </span><span class="n">s</span> <span class="kd">example</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">Set</span> <span class="n">α</span><span class="o">}</span> <span class="o">(</span><span class="n">hmeas</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">i</span><span class="o">,</span> <span class="n">MeasurableSet</span> <span class="o">(</span><span class="n">f</span> <span class="n">i</span><span class="o">))</span> <span class="o">(</span><span class="n">hdis</span> <span class="o">:</span> <span class="n">Pairwise</span> <span class="o">(</span><span class="n">Disjoint</span> <span class="n">on</span> <span class="n">f</span><span class="o">))</span> <span class="o">:</span> <span class="n">μ</span> <span class="o">(</span><span class="bp">⋃</span> <span class="n">i</span><span class="o">,</span> <span class="n">f</span> <span class="n">i</span><span class="o">)</span> <span class="bp">=</span> <span class="bp">∑'</span> <span class="n">i</span><span class="o">,</span> <span class="n">μ</span> <span class="o">(</span><span class="n">f</span> <span class="n">i</span><span class="o">)</span> <span class="o">:=</span> <span class="n">μ.m_iUnion</span> <span class="n">hmeas</span> <span class="n">hdis</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hmeas</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">MeasurableSet</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">i</span><span class="o">))</span><span class="w"> </span><span class="o">(</span><span class="n">hdis</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Pairwise</span><span class="w"> </span><span class="o">(</span><span class="n">Disjoint</span><span class="w"> </span><span class="n">on</span><span class="w"> </span><span class="n">f</span><span class="o">))</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">μ</span><span class="w"> </span><span class="o">(</span><span class="bp">⋃</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">∑'</span><span class="w"> </span><span class="n">i</span><span class="o">,</span><span class="w"> </span><span class="n">μ</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">i</span><span class="o">)</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">μ.m_iUnion</span><span class="w"> </span><span class="n">hmeas</span><span class="w"> </span><span class="n">hdis</span> </pre></div> </div> <p>Once a type has a measure associated with it, we say that a property <code class="docutils literal notranslate"><span class="pre">P</span></code>
-
@@ -204,8 +205,8 @@ has measure 0.The collection of properties that hold almost everywhere form a filter, but Mathlib introduces special notation for saying that a property holds almost everywhere.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">P</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="kt">Prop</span><span class="o">}</span> <span class="o">:</span> <span class="o">(</span><span class="bp">∀ᵐ</span> <span class="n">x</span> <span class="bp">∂</span><span class="n">μ</span><span class="o">,</span> <span class="n">P</span> <span class="n">x</span><span class="o">)</span> <span class="bp">↔</span> <span class="bp">∀ᶠ</span> <span class="n">x</span> <span class="k">in</span> <span class="n">ae</span> <span class="n">μ</span><span class="o">,</span> <span class="n">P</span> <span class="n">x</span> <span class="o">:=</span> <span class="n">Iff.rfl</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">P</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="kt">Prop</span><span class="o">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="o">(</span><span class="bp">∀ᵐ</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∂</span><span class="n">μ</span><span class="o">,</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">↔</span><span class="w"> </span><span class="bp">∀ᶠ</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">ae</span><span class="w"> </span><span class="n">μ</span><span class="o">,</span><span class="w"> </span><span class="n">P</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">Iff.rfl</span> </pre></div> </div> </section>
-
@@ -220,11 +221,11 @@ that an integral is equal to zero if the function in question isnot integrable. Most lemmas having to do with integrals have integrability assumptions.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">section</span> <span class="kd">variable</span> <span class="o">{</span><span class="n">E</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NormedAddCommGroup</span> <span class="n">E</span><span class="o">]</span> <span class="o">[</span><span class="n">NormedSpace</span> <span class="n">ℝ</span> <span class="n">E</span><span class="o">]</span> <span class="o">[</span><span class="n">CompleteSpace</span> <span class="n">E</span><span class="o">]</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">E</span><span class="o">}</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">E</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">NormedAddCommGroup</span><span class="w"> </span><span class="n">E</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">NormedSpace</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="n">E</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">CompleteSpace</span><span class="w"> </span><span class="n">E</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">E</span><span class="o">}</span> <span class="kd">example</span> <span class="o">{</span><span class="n">f</span> <span class="n">g</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">E</span><span class="o">}</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">Integrable</span> <span class="n">f</span> <span class="n">μ</span><span class="o">)</span> <span class="o">(</span><span class="n">hg</span> <span class="o">:</span> <span class="n">Integrable</span> <span class="n">g</span> <span class="n">μ</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∫</span> <span class="n">a</span><span class="o">,</span> <span class="n">f</span> <span class="n">a</span> <span class="bp">+</span> <span class="n">g</span> <span class="n">a</span> <span class="bp">∂</span><span class="n">μ</span> <span class="bp">=</span> <span class="bp">∫</span> <span class="n">a</span><span class="o">,</span> <span class="n">f</span> <span class="n">a</span> <span class="bp">∂</span><span class="n">μ</span> <span class="bp">+</span> <span class="bp">∫</span> <span class="n">a</span><span class="o">,</span> <span class="n">g</span> <span class="n">a</span> <span class="bp">∂</span><span class="n">μ</span> <span class="o">:=</span> <span class="n">integral_add</span> <span class="n">hf</span> <span class="n">hg</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">E</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Integrable</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">μ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hg</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Integrable</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">μ</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∫</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∂</span><span class="n">μ</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">∫</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∂</span><span class="n">μ</span><span class="w"> </span><span class="bp">+</span><span class="w"> </span><span class="bp">∫</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∂</span><span class="n">μ</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">integral_add</span><span class="w"> </span><span class="n">hf</span><span class="w"> </span><span class="n">hg</span> </pre></div> </div> <p>As an example of the complex interactions between our various conventions, let us see how to integrate constant functions.
-
@@ -234,41 +235,41 @@ the point at infinity, to zero.For any <code class="docutils literal notranslate"><span class="pre">s</span> <span class="pre">:</span> <span class="pre">Set</span> <span class="pre">α</span></code>, if <code class="docutils literal notranslate"><span class="pre">μ</span> <span class="pre">s</span> <span class="pre">=</span> <span class="pre">⊤</span></code>, then nonzero constant functions are not integrable on <code class="docutils literal notranslate"><span class="pre">s</span></code>. In that case, their integrals are equal to zero by definition, as is <code class="docutils literal notranslate"><span class="pre">(μ</span> <span class="pre">s).toReal</span></code>. So in all cases we have the following lemma.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">α</span><span class="o">}</span> <span class="o">(</span><span class="n">c</span> <span class="o">:</span> <span class="n">E</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∫</span> <span class="n">x</span> <span class="k">in</span> <span class="n">s</span><span class="o">,</span> <span class="n">c</span> <span class="bp">∂</span><span class="n">μ</span> <span class="bp">=</span> <span class="o">(</span><span class="n">μ</span> <span class="n">s</span><span class="o">)</span><span class="bp">.</span><span class="n">toReal</span> <span class="bp">•</span> <span class="n">c</span> <span class="o">:=</span> <span class="n">setIntegral_const</span> <span class="n">c</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">α</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">c</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="o">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∫</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="bp">∂</span><span class="n">μ</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="o">(</span><span class="n">μ</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="bp">.</span><span class="n">toReal</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">setIntegral_const</span><span class="w"> </span><span class="n">c</span> </pre></div> </div> <p>We now quickly explain how to access the most important theorems in integration theory, starting with the dominated convergence theorem. There are several versions in Mathlib, and here we only show the most basic one.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">Filter</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">Filter</span> <span class="kd">example</span> <span class="o">{</span><span class="n">F</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">→</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">E</span><span class="o">}</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">E</span><span class="o">}</span> <span class="o">(</span><span class="n">bound</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">→</span> <span class="n">ℝ</span><span class="o">)</span> <span class="o">(</span><span class="n">hmeas</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">n</span><span class="o">,</span> <span class="n">AEStronglyMeasurable</span> <span class="o">(</span><span class="n">F</span> <span class="n">n</span><span class="o">)</span> <span class="n">μ</span><span class="o">)</span> <span class="o">(</span><span class="n">hint</span> <span class="o">:</span> <span class="n">Integrable</span> <span class="n">bound</span> <span class="n">μ</span><span class="o">)</span> <span class="o">(</span><span class="n">hbound</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">n</span><span class="o">,</span> <span class="bp">∀ᵐ</span> <span class="n">a</span> <span class="bp">∂</span><span class="n">μ</span><span class="o">,</span> <span class="bp">‖</span><span class="n">F</span> <span class="n">n</span> <span class="n">a</span><span class="bp">‖</span> <span class="bp">≤</span> <span class="n">bound</span> <span class="n">a</span><span class="o">)</span> <span class="o">(</span><span class="n">hlim</span> <span class="o">:</span> <span class="bp">∀ᵐ</span> <span class="n">a</span> <span class="bp">∂</span><span class="n">μ</span><span class="o">,</span> <span class="n">Tendsto</span> <span class="o">(</span><span class="k">fun</span> <span class="n">n</span> <span class="o">:</span> <span class="n">ℕ</span> <span class="bp">↦</span> <span class="n">F</span> <span class="n">n</span> <span class="n">a</span><span class="o">)</span> <span class="n">atTop</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="o">(</span><span class="n">f</span> <span class="n">a</span><span class="o">)))</span> <span class="o">:</span> <span class="n">Tendsto</span> <span class="o">(</span><span class="k">fun</span> <span class="n">n</span> <span class="bp">↦</span> <span class="bp">∫</span> <span class="n">a</span><span class="o">,</span> <span class="n">F</span> <span class="n">n</span> <span class="n">a</span> <span class="bp">∂</span><span class="n">μ</span><span class="o">)</span> <span class="n">atTop</span> <span class="o">(</span><span class="bp">𝓝</span> <span class="o">(</span><span class="bp">∫</span> <span class="n">a</span><span class="o">,</span> <span class="n">f</span> <span class="n">a</span> <span class="bp">∂</span><span class="n">μ</span><span class="o">))</span> <span class="o">:=</span> <span class="n">tendsto_integral_of_dominated_convergence</span> <span class="n">bound</span> <span class="n">hmeas</span> <span class="n">hint</span> <span class="n">hbound</span> <span class="n">hlim</span> <span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">E</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">E</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">bound</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">ℝ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hmeas</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="n">AEStronglyMeasurable</span><span class="w"> </span><span class="o">(</span><span class="n">F</span><span class="w"> </span><span class="n">n</span><span class="o">)</span><span class="w"> </span><span class="n">μ</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="n">hint</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Integrable</span><span class="w"> </span><span class="n">bound</span><span class="w"> </span><span class="n">μ</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">hbound</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">n</span><span class="o">,</span><span class="w"> </span><span class="bp">∀ᵐ</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∂</span><span class="n">μ</span><span class="o">,</span><span class="w"> </span><span class="bp">‖</span><span class="n">F</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">a</span><span class="bp">‖</span><span class="w"> </span><span class="bp">≤</span><span class="w"> </span><span class="n">bound</span><span class="w"> </span><span class="n">a</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="n">hlim</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀ᵐ</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∂</span><span class="n">μ</span><span class="o">,</span><span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">ℕ</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">a</span><span class="o">)</span><span class="w"> </span><span class="n">atTop</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="o">)))</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">Tendsto</span><span class="w"> </span><span class="o">(</span><span class="k">fun</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="bp">∫</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">F</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∂</span><span class="n">μ</span><span class="o">)</span><span class="w"> </span><span class="n">atTop</span><span class="w"> </span><span class="o">(</span><span class="n">𝓝</span><span class="w"> </span><span class="o">(</span><span class="bp">∫</span><span class="w"> </span><span class="n">a</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="bp">∂</span><span class="n">μ</span><span class="o">))</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">tendsto_integral_of_dominated_convergence</span><span class="w"> </span><span class="n">bound</span><span class="w"> </span><span class="n">hmeas</span><span class="w"> </span><span class="n">hint</span><span class="w"> </span><span class="n">hbound</span><span class="w"> </span><span class="n">hlim</span> </pre></div> </div> <p>Then we have Fubini’s theorem for integrals on product type.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">α</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">MeasurableSpace</span> <span class="n">α</span><span class="o">]</span> <span class="o">{</span><span class="n">μ</span> <span class="o">:</span> <span class="n">Measure</span> <span class="n">α</span><span class="o">}</span> <span class="o">[</span><span class="n">SigmaFinite</span> <span class="n">μ</span><span class="o">]</span> <span class="o">{</span><span class="n">β</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">MeasurableSpace</span> <span class="n">β</span><span class="o">]</span> <span class="o">{</span><span class="n">ν</span> <span class="o">:</span> <span class="n">Measure</span> <span class="n">β</span><span class="o">}</span> <span class="o">[</span><span class="n">SigmaFinite</span> <span class="n">ν</span><span class="o">]</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">α</span> <span class="bp">×</span> <span class="n">β</span> <span class="bp">→</span> <span class="n">E</span><span class="o">)</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="n">Integrable</span> <span class="n">f</span> <span class="o">(</span><span class="n">μ.prod</span> <span class="n">ν</span><span class="o">))</span> <span class="o">:</span> <span class="bp">∫</span> <span class="n">z</span><span class="o">,</span> <span class="n">f</span> <span class="n">z</span> <span class="bp">∂</span> <span class="n">μ.prod</span> <span class="n">ν</span> <span class="bp">=</span> <span class="bp">∫</span> <span class="n">x</span><span class="o">,</span> <span class="bp">∫</span> <span class="n">y</span><span class="o">,</span> <span class="n">f</span> <span class="o">(</span><span class="n">x</span><span class="o">,</span> <span class="n">y</span><span class="o">)</span> <span class="bp">∂</span><span class="n">ν</span> <span class="bp">∂</span><span class="n">μ</span> <span class="o">:=</span> <span class="n">integral_prod</span> <span class="n">f</span> <span class="n">hf</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">α</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">MeasurableSpace</span><span class="w"> </span><span class="n">α</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">μ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Measure</span><span class="w"> </span><span class="n">α</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">SigmaFinite</span><span class="w"> </span><span class="n">μ</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">β</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="w"> </span><span class="o">[</span><span class="n">MeasurableSpace</span><span class="w"> </span><span class="n">β</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">ν</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Measure</span><span class="w"> </span><span class="n">β</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">SigmaFinite</span><span class="w"> </span><span class="n">ν</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">α</span><span class="w"> </span><span class="bp">×</span><span class="w"> </span><span class="n">β</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">E</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Integrable</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">μ.prod</span><span class="w"> </span><span class="n">ν</span><span class="o">))</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∫</span><span class="w"> </span><span class="n">z</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="bp">∂</span><span class="w"> </span><span class="n">μ.prod</span><span class="w"> </span><span class="n">ν</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">∫</span><span class="w"> </span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="bp">∫</span><span class="w"> </span><span class="n">y</span><span class="o">,</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="o">,</span><span class="w"> </span><span class="n">y</span><span class="o">)</span><span class="w"> </span><span class="bp">∂</span><span class="n">ν</span><span class="w"> </span><span class="bp">∂</span><span class="n">μ</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">integral_prod</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">hf</span> </pre></div> </div> <p>There is a very general version of convolution that applies to any continuous bilinear form.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span> <span class="n">Convolution</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kn">open</span><span class="w"> </span><span class="n">Convolution</span> <span class="kd">variable</span> <span class="o">{</span><span class="bp">𝕜</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">{</span><span class="n">G</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">{</span><span class="n">E</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">{</span><span class="n">E'</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">{</span><span class="n">F</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NormedAddCommGroup</span> <span class="n">E</span><span class="o">]</span> <span class="o">[</span><span class="n">NormedAddCommGroup</span> <span class="n">E'</span><span class="o">]</span> <span class="o">[</span><span class="n">NormedAddCommGroup</span> <span class="n">F</span><span class="o">]</span> <span class="o">[</span><span class="n">NontriviallyNormedField</span> <span class="bp">𝕜</span><span class="o">]</span> <span class="o">[</span><span class="n">NormedSpace</span> <span class="bp">𝕜</span> <span class="n">E</span><span class="o">]</span> <span class="o">[</span><span class="n">NormedSpace</span> <span class="bp">𝕜</span> <span class="n">E'</span><span class="o">]</span> <span class="o">[</span><span class="n">NormedSpace</span> <span class="bp">𝕜</span> <span class="n">F</span><span class="o">]</span> <span class="o">[</span><span class="n">MeasurableSpace</span> <span class="n">G</span><span class="o">]</span> <span class="o">[</span><span class="n">NormedSpace</span> <span class="n">ℝ</span> <span class="n">F</span><span class="o">]</span> <span class="o">[</span><span class="n">CompleteSpace</span> <span class="n">F</span><span class="o">]</span> <span class="o">[</span><span class="n">Sub</span> <span class="n">G</span><span class="o">]</span> <span class="kd">variable</span><span class="w"> </span><span class="o">{</span><span class="n">𝕜</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">G</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">E</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">E'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">NormedAddCommGroup</span><span class="w"> </span><span class="n">E</span><span class="o">]</span> <span class="w"> </span><span class="o">[</span><span class="n">NormedAddCommGroup</span><span class="w"> </span><span class="n">E'</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">NormedAddCommGroup</span><span class="w"> </span><span class="n">F</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">NontriviallyNormedField</span><span class="w"> </span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">NormedSpace</span><span class="w"> </span><span class="n">𝕜</span><span class="w"> </span><span class="n">E</span><span class="o">]</span> <span class="w"> </span><span class="o">[</span><span class="n">NormedSpace</span><span class="w"> </span><span class="n">𝕜</span><span class="w"> </span><span class="n">E'</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">NormedSpace</span><span class="w"> </span><span class="n">𝕜</span><span class="w"> </span><span class="n">F</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">MeasurableSpace</span><span class="w"> </span><span class="n">G</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">NormedSpace</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="n">F</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">CompleteSpace</span><span class="w"> </span><span class="n">F</span><span class="o">]</span> <span class="w"> </span><span class="o">[</span><span class="n">Sub</span><span class="w"> </span><span class="n">G</span><span class="o">]</span> <span class="kd">example</span> <span class="o">(</span><span class="n">f</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→</span> <span class="n">E</span><span class="o">)</span> <span class="o">(</span><span class="n">g</span> <span class="o">:</span> <span class="n">G</span> <span class="bp">→</span> <span class="n">E'</span><span class="o">)</span> <span class="o">(</span><span class="n">L</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="bp">𝕜</span><span class="o">]</span> <span class="n">E'</span> <span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="bp">𝕜</span><span class="o">]</span> <span class="n">F</span><span class="o">)</span> <span class="o">(</span><span class="n">μ</span> <span class="o">:</span> <span class="n">Measure</span> <span class="n">G</span><span class="o">)</span> <span class="o">:</span> <span class="n">f</span> <span class="bp">⋆</span><span class="o">[</span><span class="n">L</span><span class="o">,</span> <span class="n">μ</span><span class="o">]</span> <span class="n">g</span> <span class="bp">=</span> <span class="k">fun</span> <span class="n">x</span> <span class="bp">↦</span> <span class="bp">∫</span> <span class="n">t</span><span class="o">,</span> <span class="n">L</span> <span class="o">(</span><span class="n">f</span> <span class="n">t</span><span class="o">)</span> <span class="o">(</span><span class="n">g</span> <span class="o">(</span><span class="n">x</span> <span class="bp">-</span> <span class="n">t</span><span class="o">))</span> <span class="bp">∂</span><span class="n">μ</span> <span class="o">:=</span> <span class="n">rfl</span> <span class="kd">example</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">E</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">G</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">E'</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">L</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="n">E'</span><span class="w"> </span><span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="n">𝕜</span><span class="o">]</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">μ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Measure</span><span class="w"> </span><span class="n">G</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">⋆</span><span class="o">[</span><span class="n">L</span><span class="o">,</span><span class="w"> </span><span class="n">μ</span><span class="o">]</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="k">fun</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">↦</span><span class="w"> </span><span class="bp">∫</span><span class="w"> </span><span class="n">t</span><span class="o">,</span><span class="w"> </span><span class="n">L</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">t</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="o">(</span><span class="n">x</span><span class="w"> </span><span class="bp">-</span><span class="w"> </span><span class="n">t</span><span class="o">))</span><span class="w"> </span><span class="bp">∂</span><span class="n">μ</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">rfl</span> </pre></div> </div> <p>Finally, Mathlib has a very general version of the change-of-variables formula.
-
@@ -276,13 +277,13 @@ In the statement below, <code class="docutils literal notranslate"><span class="pre">BorelSpace</span> <span class="pre">E</span></code> means the<span class="math notranslate nohighlight">\(\sigma\)</span>-algebra on <code class="docutils literal notranslate"><span class="pre">E</span></code> is generated by the open sets of <code class="docutils literal notranslate"><span class="pre">E</span></code>, and <code class="docutils literal notranslate"><span class="pre">IsAddHaarMeasure</span> <span class="pre">μ</span></code> means that the measure <code class="docutils literal notranslate"><span class="pre">μ</span></code> is left-invariant, gives finite mass to compact sets, and give positive mass to open sets.</p> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span> <span class="o">{</span><span class="n">E</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NormedAddCommGroup</span> <span class="n">E</span><span class="o">]</span> <span class="o">[</span><span class="n">NormedSpace</span> <span class="n">ℝ</span> <span class="n">E</span><span class="o">]</span> <span class="o">[</span><span class="n">FiniteDimensional</span> <span class="n">ℝ</span> <span class="n">E</span><span class="o">]</span> <span class="o">[</span><span class="n">MeasurableSpace</span> <span class="n">E</span><span class="o">]</span> <span class="o">[</span><span class="n">BorelSpace</span> <span class="n">E</span><span class="o">]</span> <span class="o">(</span><span class="n">μ</span> <span class="o">:</span> <span class="n">Measure</span> <span class="n">E</span><span class="o">)</span> <span class="o">[</span><span class="n">μ.IsAddHaarMeasure</span><span class="o">]</span> <span class="o">{</span><span class="n">F</span> <span class="o">:</span> <span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="o">[</span><span class="n">NormedAddCommGroup</span> <span class="n">F</span><span class="o">]</span> <span class="o">[</span><span class="n">NormedSpace</span> <span class="n">ℝ</span> <span class="n">F</span><span class="o">]</span> <span class="o">[</span><span class="n">CompleteSpace</span> <span class="n">F</span><span class="o">]</span> <span class="o">{</span><span class="n">s</span> <span class="o">:</span> <span class="n">Set</span> <span class="n">E</span><span class="o">}</span> <span class="o">{</span><span class="n">f</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span> <span class="n">E</span><span class="o">}</span> <span class="o">{</span><span class="n">f'</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span> <span class="n">E</span> <span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="n">ℝ</span><span class="o">]</span> <span class="n">E</span><span class="o">}</span> <span class="o">(</span><span class="n">hs</span> <span class="o">:</span> <span class="n">MeasurableSet</span> <span class="n">s</span><span class="o">)</span> <span class="o">(</span><span class="n">hf</span> <span class="o">:</span> <span class="bp">∀</span> <span class="n">x</span> <span class="o">:</span> <span class="n">E</span><span class="o">,</span> <span class="n">x</span> <span class="bp">∈</span> <span class="n">s</span> <span class="bp">→</span> <span class="n">HasFDerivWithinAt</span> <span class="n">f</span> <span class="o">(</span><span class="n">f'</span> <span class="n">x</span><span class="o">)</span> <span class="n">s</span> <span class="n">x</span><span class="o">)</span> <span class="o">(</span><span class="n">h_inj</span> <span class="o">:</span> <span class="n">InjOn</span> <span class="n">f</span> <span class="n">s</span><span class="o">)</span> <span class="o">(</span><span class="n">g</span> <span class="o">:</span> <span class="n">E</span> <span class="bp">→</span> <span class="n">F</span><span class="o">)</span> <span class="o">:</span> <span class="bp">∫</span> <span class="n">x</span> <span class="k">in</span> <span class="n">f</span> <span class="bp">''</span> <span class="n">s</span><span class="o">,</span> <span class="n">g</span> <span class="n">x</span> <span class="bp">∂</span><span class="n">μ</span> <span class="bp">=</span> <span class="bp">∫</span> <span class="n">x</span> <span class="k">in</span> <span class="n">s</span><span class="o">,</span> <span class="bp">|</span><span class="o">(</span><span class="n">f'</span> <span class="n">x</span><span class="o">)</span><span class="bp">.</span><span class="n">det</span><span class="bp">|</span> <span class="bp">•</span> <span class="n">g</span> <span class="o">(</span><span class="n">f</span> <span class="n">x</span><span class="o">)</span> <span class="bp">∂</span><span class="n">μ</span> <span class="o">:=</span> <span class="n">integral_image_eq_integral_abs_det_fderiv_smul</span> <span class="n">μ</span> <span class="n">hs</span> <span class="n">hf</span> <span class="n">h_inj</span> <span class="n">g</span> <div class="highlight-lean notranslate"><div class="highlight"><pre><span></span><span class="kd">example</span><span class="w"> </span><span class="o">{</span><span class="n">E</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span><span class="w"> </span><span class="o">[</span><span class="n">NormedAddCommGroup</span><span class="w"> </span><span class="n">E</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">NormedSpace</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="n">E</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">FiniteDimensional</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="n">E</span><span class="o">]</span> <span class="w"> </span><span class="o">[</span><span class="n">MeasurableSpace</span><span class="w"> </span><span class="n">E</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">BorelSpace</span><span class="w"> </span><span class="n">E</span><span class="o">]</span><span class="w"> </span><span class="o">(</span><span class="n">μ</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Measure</span><span class="w"> </span><span class="n">E</span><span class="o">)</span><span class="w"> </span><span class="o">[</span><span class="n">μ.IsAddHaarMeasure</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">F</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">Type</span><span class="bp">*</span><span class="o">}</span> <span class="w"> </span><span class="o">[</span><span class="n">NormedAddCommGroup</span><span class="w"> </span><span class="n">F</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">NormedSpace</span><span class="w"> </span><span class="n">ℝ</span><span class="w"> </span><span class="n">F</span><span class="o">]</span><span class="w"> </span><span class="o">[</span><span class="n">CompleteSpace</span><span class="w"> </span><span class="n">F</span><span class="o">]</span><span class="w"> </span><span class="o">{</span><span class="n">s</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">Set</span><span class="w"> </span><span class="n">E</span><span class="o">}</span><span class="w"> </span><span class="o">{</span><span class="n">f</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">E</span><span class="o">}</span> <span class="w"> </span><span class="o">{</span><span class="n">f'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="n">L</span><span class="o">[</span><span class="n">ℝ</span><span class="o">]</span><span class="w"> </span><span class="n">E</span><span class="o">}</span><span class="w"> </span><span class="o">(</span><span class="n">hs</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">MeasurableSet</span><span class="w"> </span><span class="n">s</span><span class="o">)</span> <span class="w"> </span><span class="o">(</span><span class="n">hf</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="bp">∀</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="o">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∈</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">HasFDerivWithinAt</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">(</span><span class="n">f'</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="n">s</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">h_inj</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">InjOn</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="n">s</span><span class="o">)</span><span class="w"> </span><span class="o">(</span><span class="n">g</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">E</span><span class="w"> </span><span class="bp">→</span><span class="w"> </span><span class="n">F</span><span class="o">)</span><span class="w"> </span><span class="o">:</span> <span class="w"> </span><span class="bp">∫</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="bp">''</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="bp">∂</span><span class="n">μ</span><span class="w"> </span><span class="bp">=</span><span class="w"> </span><span class="bp">∫</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">s</span><span class="o">,</span><span class="w"> </span><span class="bp">|</span><span class="o">(</span><span class="n">f'</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="bp">.</span><span class="n">det</span><span class="bp">|</span><span class="w"> </span><span class="bp">•</span><span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">(</span><span class="n">f</span><span class="w"> </span><span class="n">x</span><span class="o">)</span><span class="w"> </span><span class="bp">∂</span><span class="n">μ</span><span class="w"> </span><span class="o">:=</span> <span class="w"> </span><span class="n">integral_image_eq_integral_abs_det_fderiv_smul</span><span class="w"> </span><span class="n">μ</span><span class="w"> </span><span class="n">hs</span><span class="w"> </span><span class="n">hf</span><span class="w"> </span><span class="n">h_inj</span><span class="w"> </span><span class="n">g</span> </pre></div> </div> </section>
-
-
-
@@ -1,12 +1,5 @@/* * basic.css * ~~~~~~~~~ * * Sphinx stylesheet -- basic theme. * * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ /* -- main layout ----------------------------------------------------------- */
-
@@ -115,15 +108,11 @@/* -- search page ----------------------------------------------------------- */ ul.search { margin: 10px 0 0 20px; padding: 0; margin-top: 10px; } ul.search li { padding: 5px 0 5px 20px; background-image: url(file.png); background-repeat: no-repeat; background-position: 0 7px; padding: 5px 0; } ul.search li a {
-
-
-
@@ -1,1 +1,1 @@.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:normal;src:url("../fonts/fontawesome-webfont.eot?#iefix") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff2") format("woff2"),url("../fonts/fontawesome-webfont.woff") format("woff"),url("../fonts/fontawesome-webfont.ttf") format("truetype"),url("../fonts/fontawesome-webfont.svg#FontAwesome") format("svg")}.fa:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa{display:inline-block;text-decoration:inherit}li .fa{display:inline-block}li .fa-large:before,li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before,ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before{content:""}.icon-book:before{content:""}.fa-caret-down:before{content:""}.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.icon-caret-up:before{content:""}.fa-caret-left:before{content:""}.icon-caret-left:before{content:""}.fa-caret-right:before{content:""}.icon-caret-right:before{content:""}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60}.rst-versions .rst-current-version::after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge .fa-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} .clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -1,4 +1,4 @@html{box-sizing:border-box}*,*::after,*::before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}[hidden]{display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:hover,a:active{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;color:#000;text-decoration:none}mark{background:#ff0;color:#000;font-style:italic;font-weight:bold}pre,code,.rst-content tt,.rst-content code,kbd,samp{font-family:monospace,serif;_font-family:"courier new",monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:before,q:after{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}ul,ol,dl{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:0;margin:0;padding:0}label{cursor:pointer}legend{border:0;*margin-left:-7px;padding:0;white-space:normal}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*width:13px;*height:13px}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top;resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none !important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{html,body,section{background:none !important}*{box-shadow:none !important;text-shadow:none !important;filter:none !important;-ms-filter:none !important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:.5cm}p,h2,.rst-content .toctree-wrapper>p.caption,h3{orphans:3;widows:3}h2,.rst-content .toctree-wrapper>p.caption,h3{page-break-after:avoid}}.fa:before,.wy-menu-vertical li button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.rst-content p .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo,.rst-content .admonition,.btn,input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}/*! html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) */@font-face{font-family:'FontAwesome';src:url("../fonts/fontawesome-webfont.eot?v=4.7.0");src:url("../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff2?v=4.7.0") format("woff2"),url("../fonts/fontawesome-webfont.woff?v=4.7.0") format("woff"),url("../fonts/fontawesome-webfont.ttf?v=4.7.0") format("truetype"),url("../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.fa,.wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li.current>a button.toctree-expand,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content tt.download span:first-child,.rst-content code.download span:first-child,.icon{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.3333333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.2857142857em;text-align:center}.fa-ul{padding-left:0;margin-left:2.1428571429em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.1428571429em;width:2.1428571429em;top:.1428571429em;text-align:center}.fa-li.fa-lg{left:-1.8571428571em}.fa-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.wy-menu-vertical li button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.rst-content .fa-pull-left.admonition-title,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content dl dt .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.rst-content code.download span.fa-pull-left:first-child,.fa-pull-left.icon{margin-right:.3em}.fa.fa-pull-right,.wy-menu-vertical li button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.rst-content .fa-pull-right.admonition-title,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content dl dt .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.rst-content code.download span.fa-pull-right:first-child,.fa-pull-right.icon{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.wy-menu-vertical li button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.rst-content .pull-left.admonition-title,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content dl dt .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.rst-content code.download span.pull-left:first-child,.pull-left.icon{margin-right:.3em}.fa.pull-right,.wy-menu-vertical li button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.rst-content .pull-right.admonition-title,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content dl dt .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.rst-content code.download span.pull-right:first-child,.pull-right.icon{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-remove:before,.fa-close:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.rst-content .admonition-title:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-warning:before,.fa-exclamation-triangle:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-gears:before,.fa-cogs:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.wy-dropdown .caret:before,.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:""}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li.current>a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:""}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:""}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:""}.fa-euro:before,.fa-eur:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-rupee:before,.fa-inr:before{content:""}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:""}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:""}.fa-won:before,.fa-krw:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:""}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-hotel:before,.fa-bed:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-yc:before,.fa-y-combinator:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-tv:before,.fa-television:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:""}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-signing:before,.fa-sign-language:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-vcard:before,.fa-address-card:before{content:""}.fa-vcard-o:before,.fa-address-card-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li.current>a button.toctree-expand,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content tt.download span:first-child,.rst-content code.download span:first-child,.icon,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context{font-family:inherit}.fa:before,.wy-menu-vertical li button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.rst-content p .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before{font-family:"FontAwesome";display:inline-block;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa,a .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li.current>a button.toctree-expand,a .rst-content .admonition-title,.rst-content a .admonition-title,a .rst-content h1 .headerlink,.rst-content h1 a .headerlink,a .rst-content h2 .headerlink,.rst-content h2 a .headerlink,a .rst-content h3 .headerlink,.rst-content h3 a .headerlink,a .rst-content h4 .headerlink,.rst-content h4 a .headerlink,a .rst-content h5 .headerlink,.rst-content h5 a .headerlink,a .rst-content h6 .headerlink,.rst-content h6 a .headerlink,a .rst-content dl dt .headerlink,.rst-content dl dt a .headerlink,a .rst-content p .headerlink,.rst-content p a .headerlink,a .rst-content p.caption .headerlink,.rst-content p.caption a .headerlink,a .rst-content table>caption .headerlink,.rst-content table>caption a .headerlink,a .rst-content .code-block-caption .headerlink,.rst-content .code-block-caption a .headerlink,a .rst-content .eqno .headerlink,.rst-content .eqno a .headerlink,a .rst-content tt.download span:first-child,.rst-content tt.download a span:first-child,a .rst-content code.download span:first-child,.rst-content code.download a span:first-child,a .icon{display:inline-block;text-decoration:inherit}.btn .fa,.btn .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .btn button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.btn .wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.btn .rst-content .admonition-title,.rst-content .btn .admonition-title,.btn .rst-content h1 .headerlink,.rst-content h1 .btn .headerlink,.btn .rst-content h2 .headerlink,.rst-content h2 .btn .headerlink,.btn .rst-content h3 .headerlink,.rst-content h3 .btn .headerlink,.btn .rst-content h4 .headerlink,.rst-content h4 .btn .headerlink,.btn .rst-content h5 .headerlink,.rst-content h5 .btn .headerlink,.btn .rst-content h6 .headerlink,.rst-content h6 .btn .headerlink,.btn .rst-content dl dt .headerlink,.rst-content dl dt .btn .headerlink,.btn .rst-content p .headerlink,.rst-content p .btn .headerlink,.btn .rst-content table>caption .headerlink,.rst-content table>caption .btn .headerlink,.btn .rst-content .code-block-caption .headerlink,.rst-content .code-block-caption .btn .headerlink,.btn .rst-content .eqno .headerlink,.rst-content .eqno .btn .headerlink,.btn .rst-content tt.download span:first-child,.rst-content tt.download .btn span:first-child,.btn .rst-content code.download span:first-child,.rst-content code.download .btn span:first-child,.btn .icon,.nav .fa,.nav .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand,.nav .wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.nav .rst-content .admonition-title,.rst-content .nav .admonition-title,.nav .rst-content h1 .headerlink,.rst-content h1 .nav .headerlink,.nav .rst-content h2 .headerlink,.rst-content h2 .nav .headerlink,.nav .rst-content h3 .headerlink,.rst-content h3 .nav .headerlink,.nav .rst-content h4 .headerlink,.rst-content h4 .nav .headerlink,.nav .rst-content h5 .headerlink,.rst-content h5 .nav .headerlink,.nav .rst-content h6 .headerlink,.rst-content h6 .nav .headerlink,.nav .rst-content dl dt .headerlink,.rst-content dl dt .nav .headerlink,.nav .rst-content p .headerlink,.rst-content p .nav .headerlink,.nav .rst-content table>caption .headerlink,.rst-content table>caption .nav .headerlink,.nav .rst-content .code-block-caption .headerlink,.rst-content .code-block-caption .nav .headerlink,.nav .rst-content .eqno .headerlink,.rst-content .eqno .nav .headerlink,.nav .rst-content tt.download span:first-child,.rst-content tt.download .nav span:first-child,.nav .rst-content code.download span:first-child,.rst-content code.download .nav span:first-child,.nav .icon{display:inline}.btn .fa.fa-large,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.btn .rst-content .fa-large.admonition-title,.rst-content .btn .fa-large.admonition-title,.btn .rst-content h1 .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.btn .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .btn .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.btn .rst-content .code-block-caption .fa-large.headerlink,.rst-content .code-block-caption .btn .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.rst-content tt.download .btn span.fa-large:first-child,.btn .rst-content code.download span.fa-large:first-child,.rst-content code.download .btn span.fa-large:first-child,.btn .fa-large.icon,.nav .fa.fa-large,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand,.nav .rst-content .fa-large.admonition-title,.rst-content .nav .fa-large.admonition-title,.nav .rst-content h1 .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.nav .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.nav .rst-content .code-block-caption .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.nav .rst-content code.download span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.nav .fa-large.icon{line-height:.9em}.btn .fa.fa-spin,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.btn .rst-content .fa-spin.admonition-title,.rst-content .btn .fa-spin.admonition-title,.btn .rst-content h1 .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.btn .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .btn .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.btn .rst-content .code-block-caption .fa-spin.headerlink,.rst-content .code-block-caption .btn .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.rst-content tt.download .btn span.fa-spin:first-child,.btn .rst-content code.download span.fa-spin:first-child,.rst-content code.download .btn span.fa-spin:first-child,.btn .fa-spin.icon,.nav .fa.fa-spin,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand,.nav .rst-content .fa-spin.admonition-title,.rst-content .nav .fa-spin.admonition-title,.nav .rst-content h1 .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.nav .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.nav .rst-content .code-block-caption .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.nav .rst-content code.download span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.nav .fa-spin.icon{display:inline-block}.btn.fa:before,.wy-menu-vertical li button.btn.toctree-expand:before,.rst-content .btn.admonition-title:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content dl dt .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.rst-content code.download span.btn:first-child:before,.btn.icon:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.rst-content code.download span.btn:first-child:hover:before,.btn.icon:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before,.btn-mini .rst-content .admonition-title:before,.rst-content .btn-mini .admonition-title:before,.btn-mini .rst-content h1 .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.btn-mini .rst-content dl dt .headerlink:before,.rst-content dl dt .btn-mini .headerlink:before,.btn-mini .rst-content p .headerlink:before,.rst-content p .btn-mini .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.rst-content tt.download .btn-mini span:first-child:before,.btn-mini .rst-content code.download span:first-child:before,.rst-content code.download .btn-mini span:first-child:before,.btn-mini .icon:before{font-size:14px;vertical-align:-15%}.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo,.rst-content .admonition{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.wy-alert-title,.rst-content .admonition-title{color:#fff;font-weight:bold;display:block;color:#fff;background:#6ab0de;margin:-12px;padding:6px 12px;margin-bottom:12px}.wy-alert.wy-alert-danger,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.admonition{background:#fdf3f2}.wy-alert.wy-alert-danger .wy-alert-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .danger .wy-alert-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .danger .admonition-title,.rst-content .error .admonition-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition .admonition-title{background:#f29f97}.wy-alert.wy-alert-warning,.rst-content .wy-alert-warning.note,.rst-content .attention,.rst-content .caution,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.tip,.rst-content .warning,.rst-content .wy-alert-warning.seealso,.rst-content .admonition-todo,.rst-content .wy-alert-warning.admonition{background:#ffedcc}.wy-alert.wy-alert-warning .wy-alert-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .attention .wy-alert-title,.rst-content .caution .wy-alert-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .attention .admonition-title,.rst-content .caution .admonition-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .warning .admonition-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .admonition-todo .admonition-title,.rst-content .wy-alert-warning.admonition .admonition-title{background:#f0b37e}.wy-alert.wy-alert-info,.rst-content .note,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.rst-content .seealso,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.admonition{background:#e7f2fa}.wy-alert.wy-alert-info .wy-alert-title,.rst-content .note .wy-alert-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.rst-content .note .admonition-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .seealso .admonition-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition .admonition-title{background:#6ab0de}.wy-alert.wy-alert-success,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.warning,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.admonition{background:#dbfaf4}.wy-alert.wy-alert-success .wy-alert-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .hint .wy-alert-title,.rst-content .important .wy-alert-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .hint .admonition-title,.rst-content .important .admonition-title,.rst-content .tip .admonition-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition .admonition-title{background:#1abc9c}.wy-alert.wy-alert-neutral,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.admonition{background:#f3f6f6}.wy-alert.wy-alert-neutral .wy-alert-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition .admonition-title{color:#404040;background:#e1e4e5}.wy-alert.wy-alert-neutral a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a{color:#2980B9}.wy-alert p:last-child,.rst-content .note p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.rst-content .seealso p:last-child,.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0px;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,0.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27AE60}.wy-tray-container li.wy-tray-item-info{background:#2980B9}.wy-tray-container li.wy-tray-item-warning{background:#E67E22}.wy-tray-container li.wy-tray-item-danger{background:#E74C3C}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width: 768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px 12px;color:#fff;border:1px solid rgba(0,0,0,0.1);background-color:#27AE60;text-decoration:none;font-weight:normal;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:0px 1px 2px -1px rgba(255,255,255,0.5) inset,0px -2px 0px 0px rgba(0,0,0,0.1) inset;outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:0px -1px 0px 0px rgba(0,0,0,0.05) inset,0px 2px 0px 0px rgba(0,0,0,0.1) inset;padding:8px 12px 6px 12px}.btn:visited{color:#fff}.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn-disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn-disabled:hover,.btn-disabled:focus,.btn-disabled:active{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980B9 !important}.btn-info:hover{background-color:#2e8ece !important}.btn-neutral{background-color:#f3f6f6 !important;color:#404040 !important}.btn-neutral:hover{background-color:#e5ebeb !important;color:#404040}.btn-neutral:visited{color:#404040 !important}.btn-success{background-color:#27AE60 !important}.btn-success:hover{background-color:#295 !important}.btn-danger{background-color:#E74C3C !important}.btn-danger:hover{background-color:#ea6153 !important}.btn-warning{background-color:#E67E22 !important}.btn-warning:hover{background-color:#e98b39 !important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f !important}.btn-link{background-color:transparent !important;color:#2980B9;box-shadow:none;border-color:transparent !important}.btn-link:hover{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:active{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:visited{color:#9B59B6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:before,.wy-btn-group:after{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:solid 1px #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,0.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980B9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:solid 1px #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type="search"]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980B9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned input,.wy-form-aligned textarea,.wy-form-aligned select,.wy-form-aligned .wy-help-inline,.wy-form-aligned label{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{border:0;margin:0;padding:0}legend{display:block;width:100%;border:0;padding:0;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label{display:block;margin:0 0 .3125em 0;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;*zoom:1;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#E74C3C}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full input[type="text"],.wy-control-group .wy-form-full input[type="password"],.wy-control-group .wy-form-full input[type="email"],.wy-control-group .wy-form-full input[type="url"],.wy-control-group .wy-form-full input[type="date"],.wy-control-group .wy-form-full input[type="month"],.wy-control-group .wy-form-full input[type="time"],.wy-control-group .wy-form-full input[type="datetime"],.wy-control-group .wy-form-full input[type="datetime-local"],.wy-control-group .wy-form-full input[type="week"],.wy-control-group .wy-form-full input[type="number"],.wy-control-group .wy-form-full input[type="search"],.wy-control-group .wy-form-full input[type="tel"],.wy-control-group .wy-form-full input[type="color"],.wy-control-group .wy-form-halves input[type="text"],.wy-control-group .wy-form-halves input[type="password"],.wy-control-group .wy-form-halves input[type="email"],.wy-control-group .wy-form-halves input[type="url"],.wy-control-group .wy-form-halves input[type="date"],.wy-control-group .wy-form-halves input[type="month"],.wy-control-group .wy-form-halves input[type="time"],.wy-control-group .wy-form-halves input[type="datetime"],.wy-control-group .wy-form-halves input[type="datetime-local"],.wy-control-group .wy-form-halves input[type="week"],.wy-control-group .wy-form-halves input[type="number"],.wy-control-group .wy-form-halves input[type="search"],.wy-control-group .wy-form-halves input[type="tel"],.wy-control-group .wy-form-halves input[type="color"],.wy-control-group .wy-form-thirds input[type="text"],.wy-control-group .wy-form-thirds input[type="password"],.wy-control-group .wy-form-thirds input[type="email"],.wy-control-group .wy-form-thirds input[type="url"],.wy-control-group .wy-form-thirds input[type="date"],.wy-control-group .wy-form-thirds input[type="month"],.wy-control-group .wy-form-thirds input[type="time"],.wy-control-group .wy-form-thirds input[type="datetime"],.wy-control-group .wy-form-thirds input[type="datetime-local"],.wy-control-group .wy-form-thirds input[type="week"],.wy-control-group .wy-form-thirds input[type="number"],.wy-control-group .wy-form-thirds input[type="search"],.wy-control-group .wy-form-thirds input[type="tel"],.wy-control-group .wy-form-thirds input[type="color"]{width:100%}.wy-control-group .wy-form-full{float:left;display:block;margin-right:2.3576520234%;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.3576520234%;width:48.8211739883%}.wy-control-group .wy-form-halves:last-child{margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n+1){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.3576520234%;width:31.7615653177%}.wy-control-group .wy-form-thirds:last-child{margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control{margin:6px 0 0 0;font-size:90%}.wy-control-no-input{display:inline-block;margin:6px 0 0 0;font-size:90%}.wy-control-group.fluid-input input[type="text"],.wy-control-group.fluid-input input[type="password"],.wy-control-group.fluid-input input[type="email"],.wy-control-group.fluid-input input[type="url"],.wy-control-group.fluid-input input[type="date"],.wy-control-group.fluid-input input[type="month"],.wy-control-group.fluid-input input[type="time"],.wy-control-group.fluid-input input[type="datetime"],.wy-control-group.fluid-input input[type="datetime-local"],.wy-control-group.fluid-input input[type="week"],.wy-control-group.fluid-input input[type="number"],.wy-control-group.fluid-input input[type="search"],.wy-control-group.fluid-input input[type="tel"],.wy-control-group.fluid-input input[type="color"]{width:100%}.wy-form-message-inline{display:inline-block;padding-left:.3em;color:#666;vertical-align:middle;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;*overflow:visible}input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type="datetime-local"]{padding:.34375em .625em}input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}input[type="text"]:focus,input[type="password"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus{outline:0;outline:thin dotted \9 ;border-color:#333}input.no-focus:focus{border-color:#ccc !important}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:1px auto #129FEA}input[type="text"][disabled],input[type="password"][disabled],input[type="email"][disabled],input[type="url"][disabled],input[type="date"][disabled],input[type="month"][disabled],input[type="time"][disabled],input[type="datetime"][disabled],input[type="datetime-local"][disabled],input[type="week"][disabled],input[type="number"][disabled],input[type="search"][disabled],input[type="tel"][disabled],input[type="color"][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#E74C3C;border:1px solid #E74C3C}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#E74C3C}input[type="file"]:focus:invalid:focus,input[type="radio"]:focus:invalid:focus,input[type="checkbox"]:focus:invalid:focus{outline-color:#E74C3C}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type="radio"][disabled],input[type="checkbox"][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:solid 1px #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{position:absolute;content:"";display:block;left:0;top:0;width:36px;height:12px;border-radius:4px;background:#ccc;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{position:absolute;content:"";display:block;width:18px;height:18px;border-radius:4px;background:#999;left:-3px;top:-3px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27AE60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#E74C3C}.wy-control-group.wy-control-group-error input[type="text"],.wy-control-group.wy-control-group-error input[type="password"],.wy-control-group.wy-control-group-error input[type="email"],.wy-control-group.wy-control-group-error input[type="url"],.wy-control-group.wy-control-group-error input[type="date"],.wy-control-group.wy-control-group-error input[type="month"],.wy-control-group.wy-control-group-error input[type="time"],.wy-control-group.wy-control-group-error input[type="datetime"],.wy-control-group.wy-control-group-error input[type="datetime-local"],.wy-control-group.wy-control-group-error input[type="week"],.wy-control-group.wy-control-group-error input[type="number"],.wy-control-group.wy-control-group-error input[type="search"],.wy-control-group.wy-control-group-error input[type="tel"],.wy-control-group.wy-control-group-error input[type="color"]{border:solid 1px #E74C3C}.wy-control-group.wy-control-group-error textarea{border:solid 1px #E74C3C}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27AE60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#E74C3C}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#E67E22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980B9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width: 480px){.wy-form button[type="submit"]{margin:.7em 0 0}.wy-form input[type="text"],.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:.3em;display:block}.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0 0}.wy-form .wy-help-inline,.wy-form-message-inline,.wy-form-message{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width: 768px){.tablet-hide{display:none}}@media screen and (max-width: 480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.wy-table,.rst-content table.docutils,.rst-content table.field-list{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.wy-table caption,.rst-content table.docutils caption,.rst-content table.field-list caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td,.wy-table th,.rst-content table.docutils th,.rst-content table.field-list th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.wy-table td:first-child,.rst-content table.docutils td:first-child,.rst-content table.field-list td:first-child,.wy-table th:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list th:first-child{border-left-width:0}.wy-table thead,.rst-content table.docutils thead,.rst-content table.field-list thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.wy-table thead th,.rst-content table.docutils thead th,.rst-content table.field-list thead th{font-weight:bold;border-bottom:solid 2px #e1e4e5}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td{background-color:transparent;vertical-align:middle}.wy-table td p,.rst-content table.docutils td p,.rst-content table.field-list td p{line-height:18px}.wy-table td p:last-child,.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child{margin-bottom:0}.wy-table .wy-table-cell-min,.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min{width:1%;padding-right:0}.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:gray;font-size:90%}.wy-table-tertiary{color:gray;font-size:80%}.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td,.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td{background-color:#f3f6f6}.wy-table-backed{background-color:#f3f6f6}.wy-table-bordered-all,.rst-content table.docutils{border:1px solid #e1e4e5}.wy-table-bordered-all td,.rst-content table.docutils td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.wy-table-bordered-all tbody>tr:last-child td,.rst-content table.docutils tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px 0;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0 !important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980B9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9B59B6}html{height:100%;overflow-x:hidden}body{font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;font-weight:normal;color:#404040;min-height:100%;overflow-x:hidden;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#E67E22 !important}a.wy-text-warning:hover{color:#eb9950 !important}.wy-text-info{color:#2980B9 !important}a.wy-text-info:hover{color:#409ad5 !important}.wy-text-success{color:#27AE60 !important}a.wy-text-success:hover{color:#36d278 !important}.wy-text-danger{color:#E74C3C !important}a.wy-text-danger:hover{color:#ed7669 !important}.wy-text-neutral{color:#404040 !important}a.wy-text-neutral:hover{color:#595959 !important}h1,h2,.rst-content .toctree-wrapper>p.caption,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif}p{line-height:24px;margin:0;font-size:16px;margin-bottom:24px}h1{font-size:175%}h2,.rst-content .toctree-wrapper>p.caption{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}code,.rst-content tt,.rst-content code{white-space:nowrap;max-width:100%;background:#fff;border:solid 1px #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace;color:#E74C3C;overflow-x:auto}code.code-large,.rst-content tt.code-large{font-size:90%}.wy-plain-list-disc,.rst-content .section ul,.rst-content section ul,.rst-content .toctree-wrapper ul,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.wy-plain-list-disc li,.rst-content .section ul li,.rst-content section ul li,.rst-content .toctree-wrapper ul li,article ul li{list-style:disc;margin-left:24px}.wy-plain-list-disc li p:last-child,.rst-content .section ul li p:last-child,.rst-content section ul li p:last-child,.rst-content .toctree-wrapper ul li p:last-child,article ul li p:last-child{margin-bottom:0}.wy-plain-list-disc li ul,.rst-content .section ul li ul,.rst-content section ul li ul,.rst-content .toctree-wrapper ul li ul,article ul li ul{margin-bottom:0}.wy-plain-list-disc li li,.rst-content .section ul li li,.rst-content section ul li li,.rst-content .toctree-wrapper ul li li,article ul li li{list-style:circle}.wy-plain-list-disc li li li,.rst-content .section ul li li li,.rst-content section ul li li li,.rst-content .toctree-wrapper ul li li li,article ul li li li{list-style:square}.wy-plain-list-disc li ol li,.rst-content .section ul li ol li,.rst-content section ul li ol li,.rst-content .toctree-wrapper ul li ol li,article ul li ol li{list-style:decimal}.wy-plain-list-decimal,.rst-content .section ol,.rst-content .section ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.wy-plain-list-decimal li,.rst-content .section ol li,.rst-content .section ol.arabic li,.rst-content section ol li,.rst-content section ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content .toctree-wrapper ol.arabic li,article ol li{list-style:decimal;margin-left:24px}.wy-plain-list-decimal li p:last-child,.rst-content .section ol li p:last-child,.rst-content section ol li p:last-child,.rst-content .toctree-wrapper ol li p:last-child,article ol li p:last-child{margin-bottom:0}.wy-plain-list-decimal li ul,.rst-content .section ol li ul,.rst-content .section ol.arabic li ul,.rst-content section ol li ul,.rst-content section ol.arabic li ul,.rst-content .toctree-wrapper ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,article ol li ul{margin-bottom:0}.wy-plain-list-decimal li ul li,.rst-content .section ol li ul li,.rst-content .section ol.arabic li ul li,.rst-content section ol li ul li,.rst-content section ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:before,.wy-breadcrumbs:after{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs>li code,.wy-breadcrumbs>li .rst-content tt,.rst-content .wy-breadcrumbs>li tt{all:inherit;color:inherit}.breadcrumb-item::before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width: 480px){.wy-breadcrumbs-extra{display:none}.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:before,.wy-menu-horiz:after{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz ul,.wy-menu-horiz li{display:inline-block}.wy-menu-horiz li:hover{background:rgba(255,255,255,0.1)}.wy-menu-horiz li.divide-left{border-left:solid 1px #404040}.wy-menu-horiz li.divide-right{border-right:solid 1px #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0 0;display:block;font-weight:bold;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:solid 1px #404040}.wy-menu-vertical li.divide-bottom{border-bottom:solid 1px #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:gray;border-right:solid 1px #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.wy-menu-vertical li code,.wy-menu-vertical li .rst-content tt,.rst-content .wy-menu-vertical li tt{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a{color:#404040;padding:.4045em 1.618em;font-weight:bold;position:relative;background:#fcfcfc;border:none;padding-left:1.618em -4px}.wy-menu-vertical li.on a:hover,.wy-menu-vertical li.current>a:hover{background:#fcfcfc}.wy-menu-vertical li.on a:hover button.toctree-expand,.wy-menu-vertical li.current>a:hover button.toctree-expand{color:gray}.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li.current>a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:solid 1px #c9c9c9;border-top:solid 1px #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:gray}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 4.045em;padding-right:1.618em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 5.663em;padding-right:1.618em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 7.281em;padding-right:1.618em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 8.899em;padding-right:1.618em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 10.517em;padding-right:1.618em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 12.135em;padding-right:1.618em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 13.753em;padding-right:1.618em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 15.371em;padding-right:1.618em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 16.989em;padding-right:1.618em}.wy-menu-vertical li.toctree-l2.current>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:normal}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980B9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980B9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em auto;height:45px;width:45px;background-color:#2980B9;padding:5px;border-radius:100%}.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a{color:#fcfcfc;font-size:100%;font-weight:bold;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search>a:hover,.wy-side-nav-search .wy-dropdown>a:hover{background:rgba(255,255,255,0.1)}.wy-side-nav-search>a img.logo,.wy-side-nav-search .wy-dropdown>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search>a.icon img.logo,.wy-side-nav-search .wy-dropdown>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:normal;color:rgba(255,255,255,0.3)}.wy-nav .wy-menu-vertical header{color:#2980B9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980B9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980B9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:before,.wy-nav-top:after{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:bold}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980B9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,0.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:gray}footer p{margin-bottom:12px}footer span.commit code,footer span.commit .rst-content tt,.rst-content footer span.commit tt{padding:0px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace;font-size:1em;background:none;border:none;color:gray}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:before,.rst-footer-buttons:after{width:100%}.rst-footer-buttons:before,.rst-footer-buttons:after{display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:before,.rst-breadcrumbs-buttons:after{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:solid 1px #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:solid 1px #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:gray;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width: 768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-side-scroll{width:auto}.wy-side-nav-search{width:auto}.wy-menu.wy-menu-vertical{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width: 1100px){.wy-nav-content-wrap{background:rgba(0,0,0,0.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,footer,.wy-nav-side{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .icon{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content h1,.rst-content h2,.rst-content .toctree-wrapper>p.caption,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0px}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>img,.rst-content .section>a>img,.rst-content section>img,.rst-content section>a>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px 12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace;display:block;overflow:auto}.rst-content pre.literal-block,.rst-content div[class^='highlight']{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px 0}.rst-content pre.literal-block div[class^='highlight'],.rst-content div[class^='highlight'] div[class^='highlight']{padding:0px;border:none;margin:0}.rst-content div[class^='highlight'] td.code{width:100%}.rst-content .linenodiv pre{border-right:solid 1px #e6e9ea;margin:0;padding:12px 12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^='highlight'] pre{white-space:pre;margin:0;padding:12px 12px;display:block;overflow:auto}.rst-content div[class^='highlight'] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content pre.literal-block,.rst-content div[class^='highlight'] pre,.rst-content .linenodiv pre{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight span.linenos,.rst-content div.highlight .gp{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0px;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^='highlight'],.rst-content div[class^='highlight'] pre{white-space:pre-wrap}}.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo,.rst-content .admonition{clear:both}.rst-content .note .last,.rst-content .note>*:last-child,.rst-content .attention .last,.rst-content .attention>*:last-child,.rst-content .caution .last,.rst-content .caution>*:last-child,.rst-content .danger .last,.rst-content .danger>*:last-child,.rst-content .error .last,.rst-content .error>*:last-child,.rst-content .hint .last,.rst-content .hint>*:last-child,.rst-content .important .last,.rst-content .important>*:last-child,.rst-content .tip .last,.rst-content .tip>*:last-child,.rst-content .warning .last,.rst-content .warning>*:last-child,.rst-content .seealso .last,.rst-content .seealso>*:last-child,.rst-content .admonition-todo .last,.rst-content .admonition-todo>*:last-child,.rst-content .admonition .last,.rst-content .admonition>*:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,0.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent !important;border-color:rgba(0,0,0,0.1) !important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content section ol li>*,.rst-content section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>*:first-child,.rst-content .section ul li>*:first-child,.rst-content section ol li>*:first-child,.rst-content section ul li>*:first-child,.rst-content .toctree-wrapper ol li>*:first-child,.rst-content .toctree-wrapper ul li>*:first-child{margin-top:0rem}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child{margin-bottom:0rem}.rst-content .section ol li>ul,.rst-content .section ol li>ol,.rst-content .section ul li>ul,.rst-content .section ul li>ol,.rst-content section ol li>ul,.rst-content section ol li>ol,.rst-content section ul li>ul,.rst-content section ul li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content .toctree-wrapper ul li>ol{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ul.simple li>*,.rst-content section ol.simple li>*,.rst-content section ul.simple li>*,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ul.simple li>*{margin-top:0rem;margin-bottom:0rem}.rst-content .section ol.simple li ul,.rst-content .section ol.simple li ol,.rst-content .section ul.simple li ul,.rst-content .section ul.simple li ol,.rst-content section ol.simple li ul,.rst-content section ol.simple li ol,.rst-content section ul.simple li ul,.rst-content section ul.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content .toctree-wrapper ul.simple li ol{margin-top:0rem;margin-bottom:0rem}.rst-content .line-block{margin-left:0px;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0px}.rst-content .topic-title{font-weight:bold;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0px 0px 24px 24px}.rst-content .align-left{float:left;margin:0px 24px 24px 0px}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p .headerlink,.rst-content p.caption .headerlink,.rst-content table>caption .headerlink,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content h1 .headerlink:focus,.rst-content h2 .headerlink:focus,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content h3 .headerlink:focus,.rst-content h4 .headerlink:focus,.rst-content h5 .headerlink:focus,.rst-content h6 .headerlink:focus,.rst-content dl dt .headerlink:focus,.rst-content p .headerlink:focus,.rst-content p.caption .headerlink:focus,.rst-content table>caption .headerlink:focus,.rst-content .code-block-caption .headerlink:focus,.rst-content .eqno .headerlink:focus{opacity:1}.rst-content h1:hover .headerlink,.rst-content h2:hover .headerlink,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content h3:hover .headerlink,.rst-content h4:hover .headerlink,.rst-content h5:hover .headerlink,.rst-content h6:hover .headerlink,.rst-content dl dt:hover .headerlink,.rst-content p:hover .headerlink,.rst-content p.caption:hover .headerlink,.rst-content table>caption:hover .headerlink,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table th p,.rst-content table.docutils th p,.rst-content table.field-list th p,.rst-content .wy-table th ul,.rst-content table.docutils th ul,.rst-content table.field-list th ul,.rst-content .wy-table td p,.rst-content table.docutils td p,.rst-content table.field-list td p,.rst-content .wy-table td ul,.rst-content table.docutils td ul,.rst-content table.field-list td ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:solid 1px #e1e4e5}.rst-content .sidebar p,.rst-content .sidebar ul,.rst-content .sidebar dl{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>*:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif;font-weight:bold;background:#e1e4e5;padding:6px 12px;margin:-24px;margin-bottom:24px;font-size:100%}.rst-content .highlighted{background:#F1C40F;box-shadow:0 0 0 2px #F1C40F;display:inline;font-weight:bold}.rst-content .footnote-reference,.rst-content .citation-reference{vertical-align:baseline;position:relative;top:-0.4em;line-height:0;font-size:90%}.rst-content .footnote-reference>span.fn-bracket,.rst-content .citation-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none !important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent !important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.footnote,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list{display:grid;grid-template-columns:auto minmax(80%, 95%)}html.writer-html5 .rst-content dl.footnote>dt,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem, auto) minmax(40%, 95%)}html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.footnote,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list{margin-bottom:24px}html.writer-html5 .rst-content dl.footnote>dt,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt{padding-left:1rem}html.writer-html5 .rst-content dl.footnote>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.field-list>dd{margin-bottom:0rem}html.writer-html5 .rst-content dl.footnote,html.writer-html5 .rst-content dl.citation{font-size:.9rem}html.writer-html5 .rst-content dl.footnote>dt,html.writer-html5 .rst-content dl.citation>dt{margin:0rem .5rem .5rem 0rem;line-height:1.2rem;word-break:break-all;font-weight:normal}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before,html.writer-html5 .rst-content dl.citation>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after,html.writer-html5 .rst-content dl.citation>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref,html.writer-html5 .rst-content dl.citation>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-0.1rem;max-width:5rem}html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child)::before,html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child)::before{content:" "}html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.citation>dd{margin:0rem 0rem .5rem 0rem;line-height:1.2rem}html.writer-html5 .rst-content dl.footnote>dd p,html.writer-html5 .rst-content dl.citation>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-0.1rem;max-width:5rem}html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child)::before,html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child)::before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child)::before{content:" "}html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}html.writer-html4 .rst-content table.docutils.citation,.rst-content table.docutils.footnote,html.writer-html5 .rst-content dl.footnote,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation{color:gray}html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html4 .rst-content table.docutils.citation code,.rst-content table.docutils.footnote tt,.rst-content table.docutils.footnote code,html.writer-html5 .rst-content dl.footnote tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content div.citation-list>div.citation code{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils th>p,html.writer-html5 .rst-content table.docutils td>p{line-height:1rem;margin-bottom:0rem;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>*:last-child{margin-bottom:0}.rst-content table.field-list{border:none}.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content tt,.rst-content tt,.rst-content code{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace;padding:2px 5px}.rst-content tt big,.rst-content tt em,.rst-content tt big,.rst-content code big,.rst-content tt em,.rst-content code em{font-size:100% !important;line-height:normal}.rst-content tt.literal,.rst-content tt.literal,.rst-content code.literal{color:#E74C3C;white-space:normal}.rst-content tt.xref,a .rst-content tt,.rst-content tt.xref,.rst-content code.xref,a .rst-content tt,a .rst-content code{font-weight:bold;color:#404040;overflow-wrap:normal}.rst-content pre,.rst-content kbd,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace}.rst-content a tt,.rst-content a tt,.rst-content a code{color:#2980B9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:bold;margin-bottom:12px}.rst-content dl p,.rst-content dl table,.rst-content dl ul,.rst-content dl ol{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>p:last-child,.rst-content dl dd>ol:last-child,.rst-content dl dd>ul:last-child,.rst-content dl dd>table:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980B9;border-top:solid 3px #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100% !important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:solid 3px #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100% !important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname{background-color:transparent;border:none;padding:0;font-size:100% !important}html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname{font-weight:bold}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:bold}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace;color:#000}.rst-content .viewcode-link,.rst-content .viewcode-back{display:inline-block;color:#27AE60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:bold}.rst-content tt.download,.rst-content code.download{background:inherit;padding:inherit;font-weight:normal;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content tt.download span:first-child,.rst-content code.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content *:not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd,.rst-content *:not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:grey 0px 2px;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width: 480px){.rst-content .sidebar{width:100%}}span[id*='MathJax-Span']{color:#404040}.math{text-align:center}@font-face{font-family:"Lato";src:url("../fonts/Lato-Regular.woff2") format("woff2"),url("../fonts/Lato-Regular.ttf") format("truetype");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:"Lato";src:url("../fonts/Lato-Bold.woff2") format("woff2"),url("../fonts/Lato-Bold.ttf") format("truetype");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:"Lato";src:url("../fonts/Lato-BoldItalic.woff2") format("woff2"),url("../fonts/Lato-BoldItalic.ttf") format("truetype");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:"Lato";src:url("../fonts/Lato-Italic.woff2") format("woff2"),url("../fonts/Lato-Italic.ttf") format("truetype");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:"Roboto Slab";font-style:normal;font-weight:400;src:url("../fonts/RobotoSlab-Regular.woff2") format("woff2");font-display:block}@font-face{font-family:"Roboto Slab";font-style:normal;font-weight:700;src:url("../fonts/RobotoSlab-Bold.woff2") format("woff2");font-display:block} */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search .wy-dropdown>aactive,.wy-side-nav-search .wy-dropdown>afocus,.wy-side-nav-search>a:hover,.wy-side-nav-search>aactive,.wy-side-nav-search>afocus{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon,.wy-side-nav-search>a.icon{display:block}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.switch-menus{position:relative;display:block;margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-side-nav-search>div.switch-menus>div.language-switch,.wy-side-nav-search>div.switch-menus>div.version-switch{display:inline-block;padding:.2em}.wy-side-nav-search>div.switch-menus>div.language-switch select,.wy-side-nav-search>div.switch-menus>div.version-switch select{display:inline-block;margin-right:-2rem;padding-right:2rem;max-width:240px;text-align-last:center;background:none;border:none;border-radius:0;box-shadow:none;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-size:1em;font-weight:400;color:hsla(0,0%,100%,.3);cursor:pointer;appearance:none;-webkit-appearance:none;-moz-appearance:none}.wy-side-nav-search>div.switch-menus>div.language-switch select:active,.wy-side-nav-search>div.switch-menus>div.language-switch select:focus,.wy-side-nav-search>div.switch-menus>div.language-switch select:hover,.wy-side-nav-search>div.switch-menus>div.version-switch select:active,.wy-side-nav-search>div.switch-menus>div.version-switch select:focus,.wy-side-nav-search>div.switch-menus>div.version-switch select:hover{background:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.5)}.wy-side-nav-search>div.switch-menus>div.language-switch select option,.wy-side-nav-search>div.switch-menus>div.version-switch select option{color:#000}.wy-side-nav-search>div.switch-menus>div.language-switch:has(>select):after,.wy-side-nav-search>div.switch-menus>div.version-switch:has(>select):after{display:inline-block;width:1.5em;height:100%;padding:.1em;content:"\f0d7";font-size:1em;line-height:1.2em;font-family:FontAwesome;text-align:center;pointer-events:none;box-sizing:border-box}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block}
-
-
-
@@ -1,12 +1,5 @@/* * doctools.js * ~~~~~~~~~~~ * * Base JavaScript utilities for all Sphinx HTML documentation. * * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ "use strict";
-
-
html/_static/fonts/Lato-Bold.ttf (deleted)
-
html/_static/fonts/Lato-Bold.woff2 (deleted)
-
html/_static/fonts/Lato-BoldItalic.ttf (deleted)
-
html/_static/fonts/Lato-BoldItalic.woff2 (deleted)
-
html/_static/fonts/Lato-Italic.ttf (deleted)
-
html/_static/fonts/Lato-Italic.woff2 (deleted)
-
html/_static/fonts/Lato-Regular.ttf (deleted)
-
html/_static/fonts/Lato-Regular.woff2 (deleted)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
html/_static/fonts/RobotoSlab-Bold.woff2 (deleted)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -1,2 +1,2 @@/*! jQuery v3.6.1 | (c) OpenJS Foundation and other contributors | jquery.org/license */ !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(e.document)return t(e);throw new Error("jQuery requires a window with a document")}:t(e)}("undefined"!=typeof window?window:this,function(w,R){"use strict";function v(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item}function g(e){return null!=e&&e===e.window}var t=[],M=Object.getPrototypeOf,s=t.slice,I=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},W=t.push,F=t.indexOf,$={},B=$.toString,_=$.hasOwnProperty,z=_.toString,U=z.call(Object),y={},T=w.document,X={type:!0,src:!0,nonce:!0,noModule:!0};function V(e,t,n){var r,i,o=(n=n||T).createElement("script");if(o.text=e,t)for(r in X)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function h(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?$[B.call(e)]||"object":typeof e}var e="3.6.1",C=function(e,t){return new C.fn.init(e,t)};function G(e){var t=!!e&&"length"in e&&e.length,n=h(e);return!v(e)&&!g(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}C.fn=C.prototype={jquery:e,constructor:C,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){e=C.merge(this.constructor(),e);return e.prevObject=this,e},each:function(e){return C.each(this,e)},map:function(n){return this.pushStack(C.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(C.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(C.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,e=+e+(e<0?t:0);return this.pushStack(0<=e&&e<t?[this[e]]:[])},end:function(){return this.prevObject||this.constructor()},push:W,sort:t.sort,splice:t.splice},C.extend=C.fn.extend=function(){var e,t,n,r,i,o=arguments[0]||{},a=1,s=arguments.length,u=!1;for("boolean"==typeof o&&(u=o,o=arguments[a]||{},a++),"object"==typeof o||v(o)||(o={}),a===s&&(o=this,a--);a<s;a++)if(null!=(e=arguments[a]))for(t in e)n=e[t],"__proto__"!==t&&o!==n&&(u&&n&&(C.isPlainObject(n)||(r=Array.isArray(n)))?(i=o[t],i=r&&!Array.isArray(i)?[]:r||C.isPlainObject(i)?i:{},r=!1,o[t]=C.extend(u,i,n)):void 0!==n&&(o[t]=n));return o},C.extend({expando:"jQuery"+(e+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){return!(!e||"[object Object]"!==B.call(e))&&(!(e=M(e))||"function"==typeof(e=_.call(e,"constructor")&&e.constructor)&&z.call(e)===U)},isEmptyObject:function(e){for(var t in e)return!1;return!0},globalEval:function(e,t,n){V(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(G(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},makeArray:function(e,t){t=t||[];return null!=e&&(G(Object(e))?C.merge(t,"string"==typeof e?[e]:e):W.call(t,e)),t},inArray:function(e,t,n){return null==t?-1:F.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!=a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(G(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return I(a)},guid:1,support:y}),"function"==typeof Symbol&&(C.fn[Symbol.iterator]=t[Symbol.iterator]),C.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){$["[object "+t+"]"]=t.toLowerCase()});function r(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&C(e).is(n))break;r.push(e)}return r}function Y(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}var e=function(R){function c(e,t){return e="0x"+e.slice(1)-65536,t||(e<0?String.fromCharCode(65536+e):String.fromCharCode(e>>10|55296,1023&e|56320))}function M(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e}function I(){T()}var e,p,b,o,W,d,F,$,w,u,l,T,C,n,E,h,r,i,g,S="sizzle"+ +new Date,f=R.document,k=0,B=0,_=q(),z=q(),U=q(),y=q(),X=function(e,t){return e===t&&(l=!0),0},V={}.hasOwnProperty,t=[],G=t.pop,Y=t.push,A=t.push,Q=t.slice,v=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",a="[\\x20\\t\\r\\n\\f]",s="(?:\\\\[\\da-fA-F]{1,6}"+a+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",K="\\["+a+"*("+s+")(?:"+a+"*([*^$|!~]?=)"+a+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+s+"))|)"+a+"*\\]",Z=":("+s+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+K+")*)|.*)\\)|)",ee=new RegExp(a+"+","g"),m=new RegExp("^"+a+"+|((?:^|[^\\\\])(?:\\\\.)*)"+a+"+$","g"),te=new RegExp("^"+a+"*,"+a+"*"),ne=new RegExp("^"+a+"*([>+~]|"+a+")"+a+"*"),re=new RegExp(a+"|>"),ie=new RegExp(Z),oe=new RegExp("^"+s+"$"),x={ID:new RegExp("^#("+s+")"),CLASS:new RegExp("^\\.("+s+")"),TAG:new RegExp("^("+s+"|[*])"),ATTR:new RegExp("^"+K),PSEUDO:new RegExp("^"+Z),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+a+"*(even|odd|(([+-]|)(\\d*)n|)"+a+"*(?:([+-]|)"+a+"*(\\d+)|))"+a+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+a+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+a+"*((?:-\\d)?\\d*)"+a+"*\\)|)(?=[^-]|$)","i")},ae=/HTML$/i,se=/^(?:input|select|textarea|button)$/i,ue=/^h\d$/i,N=/^[^{]+\{\s*\[native \w/,le=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ce=/[+~]/,j=new RegExp("\\\\[\\da-fA-F]{1,6}"+a+"?|\\\\([^\\r\\n\\f])","g"),fe=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,pe=ve(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{A.apply(t=Q.call(f.childNodes),f.childNodes),t[f.childNodes.length].nodeType}catch(e){A={apply:t.length?function(e,t){Y.apply(e,Q.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function D(t,e,n,r){var i,o,a,s,u,l,c=e&&e.ownerDocument,f=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==f&&9!==f&&11!==f)return n;if(!r&&(T(e),e=e||C,E)){if(11!==f&&(s=le.exec(t)))if(i=s[1]){if(9===f){if(!(l=e.getElementById(i)))return n;if(l.id===i)return n.push(l),n}else if(c&&(l=c.getElementById(i))&&g(e,l)&&l.id===i)return n.push(l),n}else{if(s[2])return A.apply(n,e.getElementsByTagName(t)),n;if((i=s[3])&&p.getElementsByClassName&&e.getElementsByClassName)return A.apply(n,e.getElementsByClassName(i)),n}if(p.qsa&&!y[t+" "]&&(!h||!h.test(t))&&(1!==f||"object"!==e.nodeName.toLowerCase())){if(l=t,c=e,1===f&&(re.test(t)||ne.test(t))){(c=ce.test(t)&&ye(e.parentNode)||e)===e&&p.scope||((a=e.getAttribute("id"))?a=a.replace(fe,M):e.setAttribute("id",a=S)),o=(u=d(t)).length;while(o--)u[o]=(a?"#"+a:":scope")+" "+P(u[o]);l=u.join(",")}try{return A.apply(n,c.querySelectorAll(l)),n}catch(e){y(t,!0)}finally{a===S&&e.removeAttribute("id")}}}return $(t.replace(m,"$1"),e,n,r)}function q(){var n=[];function r(e,t){return n.push(e+" ")>b.cacheLength&&delete r[n.shift()],r[e+" "]=t}return r}function L(e){return e[S]=!0,e}function H(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t)}}function de(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function he(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&pe(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function O(a){return L(function(o){return o=+o,L(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in p=D.support={},W=D.isXML=function(e){var t=e&&e.namespaceURI,e=e&&(e.ownerDocument||e).documentElement;return!ae.test(t||e&&e.nodeName||"HTML")},T=D.setDocument=function(e){var e=e?e.ownerDocument||e:f;return e!=C&&9===e.nodeType&&e.documentElement&&(n=(C=e).documentElement,E=!W(C),f!=C&&(e=C.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",I,!1):e.attachEvent&&e.attachEvent("onunload",I)),p.scope=H(function(e){return n.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),p.attributes=H(function(e){return e.className="i",!e.getAttribute("className")}),p.getElementsByTagName=H(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),p.getElementsByClassName=N.test(C.getElementsByClassName),p.getById=H(function(e){return n.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),p.getById?(b.filter.ID=function(e){var t=e.replace(j,c);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E)return(t=t.getElementById(e))?[t]:[]}):(b.filter.ID=function(e){var t=e.replace(j,c);return function(e){e="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return e&&e.value===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=p.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):p.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"!==e)return o;while(n=o[i++])1===n.nodeType&&r.push(n);return r},b.find.CLASS=p.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},r=[],h=[],(p.qsa=N.test(C.querySelectorAll))&&(H(function(e){var t;n.appendChild(e).innerHTML="<a id='"+S+"'></a><select id='"+S+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&h.push("[*^$]="+a+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||h.push("\\["+a+"*(?:value|"+J+")"),e.querySelectorAll("[id~="+S+"-]").length||h.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||h.push("\\["+a+"*name"+a+"*="+a+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||h.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||h.push(".#.+[+~]"),e.querySelectorAll("\\\f"),h.push("[\\r\\n\\f]")}),H(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&h.push("name"+a+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&h.push(":enabled",":disabled"),n.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&h.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),h.push(",.*:")})),(p.matchesSelector=N.test(i=n.matches||n.webkitMatchesSelector||n.mozMatchesSelector||n.oMatchesSelector||n.msMatchesSelector))&&H(function(e){p.disconnectedMatch=i.call(e,"*"),i.call(e,"[s!='']:x"),r.push("!=",Z)}),h=h.length&&new RegExp(h.join("|")),r=r.length&&new RegExp(r.join("|")),e=N.test(n.compareDocumentPosition),g=e||N.test(n.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,t=t&&t.parentNode;return e===t||!(!t||1!==t.nodeType||!(n.contains?n.contains(t):e.compareDocumentPosition&&16&e.compareDocumentPosition(t)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},X=e?function(e,t){var n;return e===t?(l=!0,0):(n=!e.compareDocumentPosition-!t.compareDocumentPosition)||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!p.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==f&&g(f,e)?-1:t==C||t.ownerDocument==f&&g(f,t)?1:u?v(u,e)-v(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?v(u,e)-v(u,t):0;if(i===o)return he(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?he(a[r],s[r]):a[r]==f?-1:s[r]==f?1:0}),C},D.matches=function(e,t){return D(e,null,null,t)},D.matchesSelector=function(e,t){if(T(e),p.matchesSelector&&E&&!y[t+" "]&&(!r||!r.test(t))&&(!h||!h.test(t)))try{var n=i.call(e,t);if(n||p.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){y(t,!0)}return 0<D(t,C,null,[e]).length},D.contains=function(e,t){return(e.ownerDocument||e)!=C&&T(e),g(e,t)},D.attr=function(e,t){(e.ownerDocument||e)!=C&&T(e);var n=b.attrHandle[t.toLowerCase()],n=n&&V.call(b.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==n?n:p.attributes||!E?e.getAttribute(t):(n=e.getAttributeNode(t))&&n.specified?n.value:null},D.escape=function(e){return(e+"").replace(fe,M)},D.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},D.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!p.detectDuplicates,u=!p.sortStable&&e.slice(0),e.sort(X),l){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return u=null,e},o=D.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=o(t);return n},(b=D.selectors={cacheLength:50,createPseudo:L,match:x,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(j,c),e[3]=(e[3]||e[4]||e[5]||"").replace(j,c),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||D.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&D.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return x.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&ie.test(n)&&(t=d(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(j,c).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=_[e+" "];return t||(t=new RegExp("(^|"+a+")"+e+"("+a+"|$)"))&&_(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(t,n,r){return function(e){e=D.attr(e,t);return null==e?"!="===n:!n||(e+="","="===n?e===r:"!="===n?e!==r:"^="===n?r&&0===e.indexOf(r):"*="===n?r&&-1<e.indexOf(r):"$="===n?r&&e.slice(-r.length)===r:"~="===n?-1<(" "+e.replace(ee," ")+" ").indexOf(r):"|="===n&&(e===r||e.slice(0,r.length+1)===r+"-"))}},CHILD:function(h,e,t,g,y){var m="nth"!==h.slice(0,3),v="last"!==h.slice(-4),x="of-type"===e;return 1===g&&0===y?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=m!=v?"nextSibling":"previousSibling",c=e.parentNode,f=x&&e.nodeName.toLowerCase(),p=!n&&!x,d=!1;if(c){if(m){while(l){a=e;while(a=a[l])if(x?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l="only"===h&&!u&&"nextSibling"}return!0}if(u=[v?c.firstChild:c.lastChild],v&&p){d=(s=(r=(i=(o=(a=c)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1])&&r[2],a=s&&c.childNodes[s];while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if(1===a.nodeType&&++d&&a===e){i[h]=[k,s,d];break}}else if(!1===(d=p?s=(r=(i=(o=(a=e)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1]:d))while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if((x?a.nodeName.toLowerCase()===f:1===a.nodeType)&&++d&&(p&&((i=(o=a[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[k,d]),a===e))break;return(d-=y)===g||d%g==0&&0<=d/g}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||D.error("unsupported pseudo: "+e);return a[S]?a(o):1<a.length?(t=[e,e,"",o],b.setFilters.hasOwnProperty(e.toLowerCase())?L(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=v(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:L(function(e){var r=[],i=[],s=F(e.replace(m,"$1"));return s[S]?L(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:L(function(t){return function(e){return 0<D(t,e).length}}),contains:L(function(t){return t=t.replace(j,c),function(e){return-1<(e.textContent||o(e)).indexOf(t)}}),lang:L(function(n){return oe.test(n||"")||D.error("unsupported lang: "+n),n=n.replace(j,c).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=R.location&&R.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===n},focus:function(e){return e===C.activeElement&&(!C.hasFocus||C.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return ue.test(e.nodeName)},input:function(e){return se.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(e=e.getAttribute("type"))||"text"===e.toLowerCase())},first:O(function(){return[0]}),last:O(function(e,t){return[t-1]}),eq:O(function(e,t,n){return[n<0?n+t:n]}),even:O(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:O(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:O(function(e,t,n){for(var r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:O(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=function(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=function(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}(e);function me(){}function P(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function ve(a,e,t){var s=e.dir,u=e.next,l=u||s,c=t&&"parentNode"===l,f=B++;return e.first?function(e,t,n){while(e=e[s])if(1===e.nodeType||c)return a(e,t,n);return!1}:function(e,t,n){var r,i,o=[k,f];if(n){while(e=e[s])if((1===e.nodeType||c)&&a(e,t,n))return!0}else while(e=e[s])if(1===e.nodeType||c)if(i=(i=e[S]||(e[S]={}))[e.uniqueID]||(i[e.uniqueID]={}),u&&u===e.nodeName.toLowerCase())e=e[s]||e;else{if((r=i[l])&&r[0]===k&&r[1]===f)return o[2]=r[2];if((i[l]=o)[2]=a(e,t,n))return!0}return!1}}function xe(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function be(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)!(o=e[s])||n&&!n(o,r,i)||(a.push(o),l&&t.push(s));return a}function we(d,h,g,y,m,e){return y&&!y[S]&&(y=we(y)),m&&!m[S]&&(m=we(m,e)),L(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)D(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),f=!d||!e&&h?c:be(c,s,d,n,r),p=g?m||(e?d:l||y)?[]:t:f;if(g&&g(f,p,n,r),y){i=be(p,u),y(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(p[u[o]]=!(f[u[o]]=a))}if(e){if(m||d){if(m){i=[],o=p.length;while(o--)(a=p[o])&&i.push(f[o]=a);m(null,p=[],i,r)}o=p.length;while(o--)(a=p[o])&&-1<(i=m?v(e,a):s[o])&&(e[i]=!(t[i]=a))}}else p=be(p===t?p.splice(l,p.length):p),m?m(null,t,p,r):A.apply(t,p)})}function Te(y,m){function e(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG("*",i),h=k+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t==C||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){a=0,t||o.ownerDocument==C||(T(o),n=!E);while(s=y[a++])if(s(o,t||C,n)){r.push(o);break}i&&(k=h)}v&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,v&&l!==u){a=0;while(s=m[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=G.call(r));f=be(f)}A.apply(r,f),i&&!e&&0<f.length&&1<u+m.length&&D.uniqueSort(r)}return i&&(k=h,w=p),c}var v=0<m.length,x=0<y.length;return v?L(e):e}return me.prototype=b.filters=b.pseudos,b.setFilters=new me,d=D.tokenize=function(e,t){var n,r,i,o,a,s,u,l=z[e+" "];if(l)return t?0:l.slice(0);a=e,s=[],u=b.preFilter;while(a){for(o in n&&!(r=te.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=ne.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace(m," ")}),a=a.slice(n.length)),b.filter)!(r=x[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?D.error(e):z(e,s).slice(0)},F=D.compile=function(e,t){var n,r=[],i=[],o=U[e+" "];if(!o){n=(t=t||d(e)).length;while(n--)((o=function e(t){for(var r,n,i,o=t.length,a=b.relative[t[0].type],s=a||b.relative[" "],u=a?1:0,l=ve(function(e){return e===r},s,!0),c=ve(function(e){return-1<v(r,e)},s,!0),f=[function(e,t,n){return e=!a&&(n||t!==w)||((r=t).nodeType?l:c)(e,t,n),r=null,e}];u<o;u++)if(n=b.relative[t[u].type])f=[ve(xe(f),n)];else{if((n=b.filter[t[u].type].apply(null,t[u].matches))[S]){for(i=++u;i<o;i++)if(b.relative[t[i].type])break;return we(1<u&&xe(f),1<u&&P(t.slice(0,u-1).concat({value:" "===t[u-2].type?"*":""})).replace(m,"$1"),n,u<i&&e(t.slice(u,i)),i<o&&e(t=t.slice(i)),i<o&&P(t))}f.push(n)}return xe(f)}(t[n]))[S]?r:i).push(o);(o=U(e,Te(i,r))).selector=e}return o},$=D.select=function(e,t,n,r){var i,o,a,s,u="function"==typeof e&&e,l=!r&&d(e=u.selector||e);if(n=n||[],1===l.length){if(2<(o=l[0]=l[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&E&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(j,c),t)||[])[0]))return n;u&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=x.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],b.relative[s=a.type])break;if((s=b.find[s])&&(r=s(a.matches[0].replace(j,c),ce.test(o[0].type)&&ye(t.parentNode)||t))){if(o.splice(i,1),e=r.length&&P(o))break;return A.apply(n,r),n}}}return(u||F(e,l))(r,t,!E,n,!t||ce.test(e)&&ye(t.parentNode)||t),n},p.sortStable=S.split("").sort(X).join("")===S,p.detectDuplicates=!!l,T(),p.sortDetached=H(function(e){return 1&e.compareDocumentPosition(C.createElement("fieldset"))}),H(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||de("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),p.attributes&&H(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||de("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),H(function(e){return null==e.getAttribute("disabled")})||de(J,function(e,t,n){if(!n)return!0===e[t]?t.toLowerCase():(n=e.getAttributeNode(t))&&n.specified?n.value:null}),D}(w),Q=(C.find=e,C.expr=e.selectors,C.expr[":"]=C.expr.pseudos,C.uniqueSort=C.unique=e.uniqueSort,C.text=e.getText,C.isXMLDoc=e.isXML,C.contains=e.contains,C.escapeSelector=e.escape,C.expr.match.needsContext);function u(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var J=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function K(e,n,r){return v(n)?C.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?C.grep(e,function(e){return e===n!==r}):"string"!=typeof n?C.grep(e,function(e){return-1<F.call(n,e)!==r}):C.filter(n,e,r)}C.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?C.find.matchesSelector(r,e)?[r]:[]:C.find.matches(e,C.grep(t,function(e){return 1===e.nodeType}))},C.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(C(e).filter(function(){for(t=0;t<r;t++)if(C.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)C.find(e,i[t],n);return 1<r?C.uniqueSort(n):n},filter:function(e){return this.pushStack(K(this,e||[],!1))},not:function(e){return this.pushStack(K(this,e||[],!0))},is:function(e){return!!K(this,"string"==typeof e&&Q.test(e)?C(e):e||[],!1).length}});var Z,ee=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,te=((C.fn.init=function(e,t,n){if(e){if(n=n||Z,"string"!=typeof e)return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(C):C.makeArray(e,this);if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:ee.exec(e))||!r[1]&&t)return(!t||t.jquery?t||n:this.constructor(t)).find(e);if(r[1]){if(t=t instanceof C?t[0]:t,C.merge(this,C.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:T,!0)),J.test(r[1])&&C.isPlainObject(t))for(var r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r])}else(n=T.getElementById(r[2]))&&(this[0]=n,this.length=1)}return this}).prototype=C.fn,Z=C(T),/^(?:parents|prev(?:Until|All))/),ne={children:!0,contents:!0,next:!0,prev:!0};function re(e,t){while((e=e[t])&&1!==e.nodeType);return e}C.fn.extend({has:function(e){var t=C(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(C.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&C(e);if(!Q.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&C.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?C.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?F.call(C(e),this[0]):F.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(C.uniqueSort(C.merge(this.get(),C(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),C.each({parent:function(e){e=e.parentNode;return e&&11!==e.nodeType?e:null},parents:function(e){return r(e,"parentNode")},parentsUntil:function(e,t,n){return r(e,"parentNode",n)},next:function(e){return re(e,"nextSibling")},prev:function(e){return re(e,"previousSibling")},nextAll:function(e){return r(e,"nextSibling")},prevAll:function(e){return r(e,"previousSibling")},nextUntil:function(e,t,n){return r(e,"nextSibling",n)},prevUntil:function(e,t,n){return r(e,"previousSibling",n)},siblings:function(e){return Y((e.parentNode||{}).firstChild,e)},children:function(e){return Y(e.firstChild)},contents:function(e){return null!=e.contentDocument&&M(e.contentDocument)?e.contentDocument:(u(e,"template")&&(e=e.content||e),C.merge([],e.childNodes))}},function(r,i){C.fn[r]=function(e,t){var n=C.map(this,i,e);return(t="Until"!==r.slice(-5)?e:t)&&"string"==typeof t&&(n=C.filter(t,n)),1<this.length&&(ne[r]||C.uniqueSort(n),te.test(r)&&n.reverse()),this.pushStack(n)}});var E=/[^\x20\t\r\n\f]+/g;function c(e){return e}function ie(e){throw e}function oe(e,t,n,r){var i;try{e&&v(i=e.promise)?i.call(e).done(t).fail(n):e&&v(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}C.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},C.each(e.match(E)||[],function(e,t){n[t]=!0}),n):C.extend({},r);function i(){for(s=s||r.once,a=o=!0;l.length;c=-1){t=l.shift();while(++c<u.length)!1===u[c].apply(t[0],t[1])&&r.stopOnFalse&&(c=u.length,t=!1)}r.memory||(t=!1),o=!1,s&&(u=t?[]:"")}var o,t,a,s,u=[],l=[],c=-1,f={add:function(){return u&&(t&&!o&&(c=u.length-1,l.push(t)),function n(e){C.each(e,function(e,t){v(t)?r.unique&&f.has(t)||u.push(t):t&&t.length&&"string"!==h(t)&&n(t)})}(arguments),t&&!o&&i()),this},remove:function(){return C.each(arguments,function(e,t){var n;while(-1<(n=C.inArray(t,u,n)))u.splice(n,1),n<=c&&c--}),this},has:function(e){return e?-1<C.inArray(e,u):0<u.length},empty:function(){return u=u&&[],this},disable:function(){return s=l=[],u=t="",this},disabled:function(){return!u},lock:function(){return s=l=[],t||o||(u=t=""),this},locked:function(){return!!s},fireWith:function(e,t){return s||(t=[e,(t=t||[]).slice?t.slice():t],l.push(t),o||i()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!a}};return f},C.extend({Deferred:function(e){var o=[["notify","progress",C.Callbacks("memory"),C.Callbacks("memory"),2],["resolve","done",C.Callbacks("once memory"),C.Callbacks("once memory"),0,"resolved"],["reject","fail",C.Callbacks("once memory"),C.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},catch:function(e){return a.then(null,e)},pipe:function(){var i=arguments;return C.Deferred(function(r){C.each(o,function(e,t){var n=v(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&v(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){function e(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,v(t)?s?t.call(e,l(u,o,c,s),l(u,o,ie,s)):(u++,t.call(e,l(u,o,c,s),l(u,o,ie,s),l(u,o,c,o.notifyWith))):(a!==c&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}}var n=this,r=arguments,t=s?e:function(){try{e()}catch(e){C.Deferred.exceptionHook&&C.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==ie&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(C.Deferred.getStackHook&&(t.stackTrace=C.Deferred.getStackHook()),w.setTimeout(t))}}return C.Deferred(function(e){o[0][3].add(l(0,e,v(r)?r:c,e.notifyWith)),o[1][3].add(l(0,e,v(t)?t:c)),o[2][3].add(l(0,e,v(n)?n:ie))}).promise()},promise:function(e){return null!=e?C.extend(e,a):a}},s={};return C.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){function t(t){return function(e){i[t]=this,o[t]=1<arguments.length?s.call(arguments):e,--n||a.resolveWith(i,o)}}var n=arguments.length,r=n,i=Array(r),o=s.call(arguments),a=C.Deferred();if(n<=1&&(oe(e,a.done(t(r)).resolve,a.reject,!n),"pending"===a.state()||v(o[r]&&o[r].then)))return a.then();while(r--)oe(o[r],t(r),a.reject);return a.promise()}});var ae=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/,se=(C.Deferred.exceptionHook=function(e,t){w.console&&w.console.warn&&e&&ae.test(e.name)&&w.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},C.readyException=function(e){w.setTimeout(function(){throw e})},C.Deferred());function ue(){T.removeEventListener("DOMContentLoaded",ue),w.removeEventListener("load",ue),C.ready()}C.fn.ready=function(e){return se.then(e).catch(function(e){C.readyException(e)}),this},C.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--C.readyWait:C.isReady)||(C.isReady=!0)!==e&&0<--C.readyWait||se.resolveWith(T,[C])}}),C.ready.then=se.then,"complete"===T.readyState||"loading"!==T.readyState&&!T.documentElement.doScroll?w.setTimeout(C.ready):(T.addEventListener("DOMContentLoaded",ue),w.addEventListener("load",ue));function f(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===h(n))for(s in i=!0,n)f(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,v(r)||(a=!0),t=l?a?(t.call(e,r),null):(l=t,function(e,t,n){return l.call(C(e),n)}):t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o}var le=/^-ms-/,ce=/-([a-z])/g;function fe(e,t){return t.toUpperCase()}function x(e){return e.replace(le,"ms-").replace(ce,fe)}function m(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType}function pe(){this.expando=C.expando+pe.uid++}pe.uid=1,pe.prototype={cache:function(e){var t=e[this.expando];return t||(t={},m(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[x(t)]=n;else for(r in t)i[x(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][x(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(x):(t=x(t))in r?[t]:t.match(E)||[]).length;while(n--)delete r[t[n]]}void 0!==t&&!C.isEmptyObject(r)||(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){e=e[this.expando];return void 0!==e&&!C.isEmptyObject(e)}};var b=new pe,l=new pe,de=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,he=/[A-Z]/g;function ge(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(he,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:de.test(i)?JSON.parse(i):i)}catch(e){}l.set(e,t,n)}else n=void 0;return n}C.extend({hasData:function(e){return l.hasData(e)||b.hasData(e)},data:function(e,t,n){return l.access(e,t,n)},removeData:function(e,t){l.remove(e,t)},_data:function(e,t,n){return b.access(e,t,n)},_removeData:function(e,t){b.remove(e,t)}}),C.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0!==n)return"object"==typeof n?this.each(function(){l.set(this,n)}):f(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=l.get(o,n))||void 0!==(t=ge(o,n))?t:void 0;this.each(function(){l.set(this,n,e)})},null,e,1<arguments.length,null,!0);if(this.length&&(i=l.get(o),1===o.nodeType&&!b.get(o,"hasDataAttrs"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=x(r.slice(5)),ge(o,r,i[r]));b.set(o,"hasDataAttrs",!0)}return i},removeData:function(e){return this.each(function(){l.remove(this,e)})}}),C.extend({queue:function(e,t,n){var r;if(e)return r=b.get(e,t=(t||"fx")+"queue"),n&&(!r||Array.isArray(n)?r=b.access(e,t,C.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=C.queue(e,t),r=n.length,i=n.shift(),o=C._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){C.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return b.get(e,n)||b.access(e,n,{empty:C.Callbacks("once memory").add(function(){b.remove(e,[t+"queue",n])})})}}),C.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?C.queue(this[0],t):void 0===n?this:this.each(function(){var e=C.queue(this,t,n);C._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&C.dequeue(this,t)})},dequeue:function(e){return this.each(function(){C.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){function n(){--i||o.resolveWith(a,[a])}var r,i=1,o=C.Deferred(),a=this,s=this.length;"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(s--)(r=b.get(a[s],e+"queueHooks"))&&r.empty&&(i++,r.empty.add(n));return n(),o.promise(t)}});function ye(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&k(e)&&"none"===C.css(e,"display")}var e=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,me=new RegExp("^(?:([+-])=|)("+e+")([a-z%]*)$","i"),p=["Top","Right","Bottom","Left"],S=T.documentElement,k=function(e){return C.contains(e.ownerDocument,e)},ve={composed:!0};S.getRootNode&&(k=function(e){return C.contains(e.ownerDocument,e)||e.getRootNode(ve)===e.ownerDocument});function xe(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return C.css(e,t,"")},u=s(),l=n&&n[3]||(C.cssNumber[t]?"":"px"),c=e.nodeType&&(C.cssNumber[t]||"px"!==l&&+u)&&me.exec(C.css(e,t));if(c&&c[3]!==l){l=l||c[3],c=+(u/=2)||1;while(a--)C.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;C.style(e,t,(c*=2)+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var be={};function A(e,t){for(var n,r,i,o,a,s=[],u=0,l=e.length;u<l;u++)(r=e[u]).style&&(n=r.style.display,t?("none"===n&&(s[u]=b.get(r,"display")||null,s[u]||(r.style.display="")),""===r.style.display&&ye(r)&&(s[u]=(a=o=void 0,o=(i=r).ownerDocument,i=i.nodeName,(a=be[i])||(o=o.body.appendChild(o.createElement(i)),a=C.css(o,"display"),o.parentNode.removeChild(o),be[i]=a="none"===a?"block":a),a))):"none"!==n&&(s[u]="none",b.set(r,"display",n)));for(u=0;u<l;u++)null!=s[u]&&(e[u].style.display=s[u]);return e}C.fn.extend({show:function(){return A(this,!0)},hide:function(){return A(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){ye(this)?C(this).show():C(this).hide()})}});var we=/^(?:checkbox|radio)$/i,Te=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i,N=(L=T.createDocumentFragment().appendChild(T.createElement("div")),(o=T.createElement("input")).setAttribute("type","radio"),o.setAttribute("checked","checked"),o.setAttribute("name","t"),L.appendChild(o),y.checkClone=L.cloneNode(!0).cloneNode(!0).lastChild.checked,L.innerHTML="<textarea>x</textarea>",y.noCloneChecked=!!L.cloneNode(!0).lastChild.defaultValue,L.innerHTML="<option></option>",y.option=!!L.lastChild,{thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]});function j(e,t){var n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[];return void 0===t||t&&u(e,t)?C.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n<r;n++)b.set(e[n],"globalEval",!t||b.get(t[n],"globalEval"))}N.tbody=N.tfoot=N.colgroup=N.caption=N.thead,N.th=N.td,y.option||(N.optgroup=N.option=[1,"<select multiple='multiple'>","</select>"]);var Se=/<|&#?\w+;/;function ke(e,t,n,r,i){for(var o,a,s,u,l,c=t.createDocumentFragment(),f=[],p=0,d=e.length;p<d;p++)if((o=e[p])||0===o)if("object"===h(o))C.merge(f,o.nodeType?[o]:o);else if(Se.test(o)){a=a||c.appendChild(t.createElement("div")),s=(Te.exec(o)||["",""])[1].toLowerCase(),s=N[s]||N._default,a.innerHTML=s[1]+C.htmlPrefilter(o)+s[2],l=s[0];while(l--)a=a.lastChild;C.merge(f,a.childNodes),(a=c.firstChild).textContent=""}else f.push(t.createTextNode(o));c.textContent="",p=0;while(o=f[p++])if(r&&-1<C.inArray(o,r))i&&i.push(o);else if(u=k(o),a=j(c.appendChild(o),"script"),u&&Ee(a),n){l=0;while(o=a[l++])Ce.test(o.type||"")&&n.push(o)}return c}var Ae=/^([^.]*)(?:\.(.+)|)/;function n(){return!0}function d(){return!1}function Ne(e,t){return e===function(){try{return T.activeElement}catch(e){}}()==("focus"===t)}function je(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)je(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=d;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return C().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=C.guid++)),e.each(function(){C.event.add(this,t,i,r,n)})}function De(e,i,o){o?(b.set(e,i,!1),C.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=b.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(C.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),b.set(this,i,r),t=o(this,i),this[i](),r!==(n=b.get(this,i))||t?b.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n&&n.value}else r.length&&(b.set(this,i,{value:C.event.trigger(C.extend(r[0],C.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===b.get(e,i)&&C.event.add(e,i,n)}C.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h=b.get(t);if(m(t)){n.handler&&(n=(o=n).handler,i=o.selector),i&&C.find.matchesSelector(S,i),n.guid||(n.guid=C.guid++),(s=h.events)||(s=h.events=Object.create(null)),(a=h.handle)||(a=h.handle=function(e){return"undefined"!=typeof C&&C.event.triggered!==e.type?C.event.dispatch.apply(t,arguments):void 0}),u=(e=(e||"").match(E)||[""]).length;while(u--)f=d=(p=Ae.exec(e[u])||[])[1],p=(p[2]||"").split(".").sort(),f&&(l=C.event.special[f]||{},f=(i?l.delegateType:l.bindType)||f,l=C.event.special[f]||{},d=C.extend({type:f,origType:d,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&C.expr.match.needsContext.test(i),namespace:p.join(".")},o),(c=s[f])||((c=s[f]=[]).delegateCount=0,l.setup&&!1!==l.setup.call(t,r,p,a)||t.addEventListener&&t.addEventListener(f,a)),l.add&&(l.add.call(t,d),d.handler.guid||(d.handler.guid=n.guid)),i?c.splice(c.delegateCount++,0,d):c.push(d),C.event.global[f]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=b.hasData(e)&&b.get(e);if(y&&(u=y.events)){l=(t=(t||"").match(E)||[""]).length;while(l--)if(d=g=(s=Ae.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=C.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,y.handle)||C.removeEvent(e,d,y.handle),delete u[d])}else for(d in u)C.event.remove(e,d+t[l],n,r,!0);C.isEmptyObject(u)&&b.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a=new Array(arguments.length),s=C.event.fix(e),e=(b.get(this,"events")||Object.create(null))[s.type]||[],u=C.event.special[s.type]||{};for(a[0]=s,t=1;t<arguments.length;t++)a[t]=arguments[t];if(s.delegateTarget=this,!u.preDispatch||!1!==u.preDispatch.call(this,s)){o=C.event.handlers.call(this,s,e),t=0;while((r=o[t++])&&!s.isPropagationStopped()){s.currentTarget=r.elem,n=0;while((i=r.handlers[n++])&&!s.isImmediatePropagationStopped())s.rnamespace&&!1!==i.namespace&&!s.rnamespace.test(i.namespace)||(s.handleObj=i,s.data=i.data,void 0!==(i=((C.event.special[i.origType]||{}).handle||i.handler).apply(r.elem,a))&&!1===(s.result=i)&&(s.preventDefault(),s.stopPropagation()))}return u.postDispatch&&u.postDispatch.call(this,s),s.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<C(i,this).index(l):C.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(C.Event.prototype,t,{enumerable:!0,configurable:!0,get:v(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[C.expando]?e:new C.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){e=this||e;return we.test(e.type)&&e.click&&u(e,"input")&&De(e,"click",n),!1},trigger:function(e){e=this||e;return we.test(e.type)&&e.click&&u(e,"input")&&De(e,"click"),!0},_default:function(e){e=e.target;return we.test(e.type)&&e.click&&u(e,"input")&&b.get(e,"click")||u(e,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},C.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},C.Event=function(e,t){if(!(this instanceof C.Event))return new C.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?n:d,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&C.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[C.expando]=!0},C.Event.prototype={constructor:C.Event,isDefaultPrevented:d,isPropagationStopped:d,isImmediatePropagationStopped:d,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=n,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=n,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=n,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},C.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,char:!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:!0},C.event.addProp),C.each({focus:"focusin",blur:"focusout"},function(t,e){C.event.special[t]={setup:function(){return De(this,t,Ne),!1},trigger:function(){return De(this,t),!0},_default:function(e){return b.get(e.target,t)},delegateType:e}}),C.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){C.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||C.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),C.fn.extend({on:function(e,t,n,r){return je(this,e,t,n,r)},one:function(e,t,n,r){return je(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)r=e.handleObj,C(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler);else{if("object"!=typeof e)return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=d),this.each(function(){C.event.remove(this,e,n,t)});for(i in e)this.off(i,t,e[i])}return this}});var qe=/<script|<style|<link/i,Le=/checked\s*(?:[^=]|=\s*.checked.)/i,He=/^\s*<!\[CDATA\[|\]\]>\s*$/g;function Oe(e,t){return u(e,"table")&&u(11!==t.nodeType?t:t.firstChild,"tr")&&C(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o;if(1===t.nodeType){if(b.hasData(e)&&(o=b.get(e).events))for(i in b.remove(t,"handle events"),o)for(n=0,r=o[i].length;n<r;n++)C.event.add(t,i,o[i][n]);l.hasData(e)&&(e=l.access(e),e=C.extend({},e),l.set(t,e))}}function D(n,r,i,o){r=I(r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=v(d);if(h||1<f&&"string"==typeof d&&!y.checkClone&&Le.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),D(t,r,i,o)});if(f&&(t=(e=ke(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=C.map(j(e,"script"),Pe)).length;c<f;c++)u=e,c!==p&&(u=C.clone(u,!0,!0),s&&C.merge(a,j(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,C.map(a,Re),c=0;c<s;c++)u=a[c],Ce.test(u.type||"")&&!b.access(u,"globalEval")&&C.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?C._evalUrl&&!u.noModule&&C._evalUrl(u.src,{nonce:u.nonce||u.getAttribute("nonce")},l):V(u.textContent.replace(He,""),u,l))}return n}function Ie(e,t,n){for(var r,i=t?C.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||C.cleanData(j(r)),r.parentNode&&(n&&k(r)&&Ee(j(r,"script")),r.parentNode.removeChild(r));return e}C.extend({htmlPrefilter:function(e){return e},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=k(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||C.isXMLDoc(e)))for(a=j(c),r=0,i=(o=j(e)).length;r<i;r++)s=o[r],u=a[r],l=void 0,"input"===(l=u.nodeName.toLowerCase())&&we.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||j(e),a=a||j(c),r=0,i=o.length;r<i;r++)Me(o[r],a[r]);else Me(e,c);return 0<(a=j(c,"script")).length&&Ee(a,!f&&j(e,"script")),c},cleanData:function(e){for(var t,n,r,i=C.event.special,o=0;void 0!==(n=e[o]);o++)if(m(n)){if(t=n[b.expando]){if(t.events)for(r in t.events)i[r]?C.event.remove(n,r):C.removeEvent(n,r,t.handle);n[b.expando]=void 0}n[l.expando]&&(n[l.expando]=void 0)}}}),C.fn.extend({detach:function(e){return Ie(this,e,!0)},remove:function(e){return Ie(this,e)},text:function(e){return f(this,function(e){return void 0===e?C.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return D(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Oe(this,e).appendChild(e)})},prepend:function(){return D(this,arguments,function(e){var t;1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(t=Oe(this,e)).insertBefore(e,t.firstChild)})},before:function(){return D(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return D(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(C.cleanData(j(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return C.clone(this,e,t)})},html:function(e){return f(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!qe.test(e)&&!N[(Te.exec(e)||["",""])[1].toLowerCase()]){e=C.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(C.cleanData(j(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return D(this,arguments,function(e){var t=this.parentNode;C.inArray(this,n)<0&&(C.cleanData(j(this)),t&&t.replaceChild(e,this))},n)}}),C.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){C.fn[e]=function(e){for(var t,n=[],r=C(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),C(r[o])[a](t),W.apply(n,t.get());return this.pushStack(n)}});function We(e){var t=e.ownerDocument.defaultView;return(t=t&&t.opener?t:w).getComputedStyle(e)}function Fe(e,t,n){var r,i={};for(r in t)i[r]=e.style[r],e.style[r]=t[r];for(r in n=n.call(e),t)e.style[r]=i[r];return n}var $e,Be,_e,ze,Ue,Xe,Ve,i,Ge=new RegExp("^("+e+")(?!px)[a-z%]+$","i"),Ye=/^--/,Qe=new RegExp(p.join("|"),"i"),o="[\\x20\\t\\r\\n\\f]",Je=new RegExp("^"+o+"+|((?:^|[^\\\\])(?:\\\\.)*)"+o+"+$","g");function Ke(){var e;i&&(Ve.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",i.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",S.appendChild(Ve).appendChild(i),e=w.getComputedStyle(i),$e="1%"!==e.top,Xe=12===Ze(e.marginLeft),i.style.right="60%",ze=36===Ze(e.right),Be=36===Ze(e.width),i.style.position="absolute",_e=12===Ze(i.offsetWidth/3),S.removeChild(Ve),i=null)}function Ze(e){return Math.round(parseFloat(e))}function et(e,t,n){var r,i=Ye.test(t),o=e.style;return(n=n||We(e))&&(r=n.getPropertyValue(t)||n[t],""!==(r=i?r.replace(Je,"$1"):r)||k(e)||(r=C.style(e,t)),!y.pixelBoxStyles()&&Ge.test(r)&&Qe.test(t)&&(i=o.width,e=o.minWidth,t=o.maxWidth,o.minWidth=o.maxWidth=o.width=r,r=n.width,o.width=i,o.minWidth=e,o.maxWidth=t)),void 0!==r?r+"":r}function tt(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}Ve=T.createElement("div"),(i=T.createElement("div")).style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",y.clearCloneStyle="content-box"===i.style.backgroundClip,C.extend(y,{boxSizingReliable:function(){return Ke(),Be},pixelBoxStyles:function(){return Ke(),ze},pixelPosition:function(){return Ke(),$e},reliableMarginLeft:function(){return Ke(),Xe},scrollboxSize:function(){return Ke(),_e},reliableTrDimensions:function(){var e,t,n;return null==Ue&&(e=T.createElement("table"),t=T.createElement("tr"),n=T.createElement("div"),e.style.cssText="position:absolute;left:-11111px;border-collapse:separate",t.style.cssText="border:1px solid",t.style.height="1px",n.style.height="9px",n.style.display="block",S.appendChild(e).appendChild(t).appendChild(n),n=w.getComputedStyle(t),Ue=parseInt(n.height,10)+parseInt(n.borderTopWidth,10)+parseInt(n.borderBottomWidth,10)===t.offsetHeight,S.removeChild(e)),Ue}}));var nt=["Webkit","Moz","ms"],rt=T.createElement("div").style,it={};function ot(e){var t=C.cssProps[e]||it[e];return t||(e in rt?e:it[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=nt.length;while(n--)if((e=nt[n]+t)in rt)return e}(e)||e)}var at=/^(none|table(?!-c[ea]).+)/,st={position:"absolute",visibility:"hidden",display:"block"},ut={letterSpacing:"0",fontWeight:"400"};function lt(e,t,n){var r=me.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function ct(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=C.css(e,n+p[a],!0,i)),r?("content"===n&&(u-=C.css(e,"padding"+p[a],!0,i)),"margin"!==n&&(u-=C.css(e,"border"+p[a]+"Width",!0,i))):(u+=C.css(e,"padding"+p[a],!0,i),"padding"!==n?u+=C.css(e,"border"+p[a]+"Width",!0,i):s+=C.css(e,"border"+p[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function ft(e,t,n){var r=We(e),i=(!y.boxSizingReliable()||n)&&"border-box"===C.css(e,"boxSizing",!1,r),o=i,a=et(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if(Ge.test(a)){if(!n)return a;a="auto"}return(!y.boxSizingReliable()&&i||!y.reliableTrDimensions()&&u(e,"tr")||"auto"===a||!parseFloat(a)&&"inline"===C.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===C.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+ct(e,t,n||(i?"border":"content"),o,r,a)+"px"}function a(e,t,n,r,i){return new a.prototype.init(e,t,n,r,i)}C.extend({cssHooks:{opacity:{get:function(e,t){if(t)return""===(t=et(e,"opacity"))?"1":t}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=x(t),u=Ye.test(t),l=e.style;if(u||(t=ot(s)),a=C.cssHooks[t]||C.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=me.exec(n))&&i[1]&&(n=xe(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||u||(n+=i&&i[3]||(C.cssNumber[s]?"":"px")),y.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o=x(t);return Ye.test(t)||(t=ot(o)),"normal"===(i=void 0===(i=(o=C.cssHooks[t]||C.cssHooks[o])&&"get"in o?o.get(e,!0,n):i)?et(e,t,r):i)&&t in ut&&(i=ut[t]),(""===n||n)&&(o=parseFloat(i),!0===n||isFinite(o))?o||0:i}}),C.each(["height","width"],function(e,a){C.cssHooks[a]={get:function(e,t,n){if(t)return!at.test(C.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?ft(e,a,n):Fe(e,st,function(){return ft(e,a,n)})},set:function(e,t,n){var r=We(e),i=!y.scrollboxSize()&&"absolute"===r.position,o=(i||n)&&"border-box"===C.css(e,"boxSizing",!1,r),n=n?ct(e,a,n,o,r):0;return o&&i&&(n-=Math.ceil(e["offset"+a[0].toUpperCase()+a.slice(1)]-parseFloat(r[a])-ct(e,a,"border",!1,r)-.5)),n&&(o=me.exec(t))&&"px"!==(o[3]||"px")&&(e.style[a]=t,t=C.css(e,a)),lt(0,t,n)}}}),C.cssHooks.marginLeft=tt(y.reliableMarginLeft,function(e,t){if(t)return(parseFloat(et(e,"marginLeft"))||e.getBoundingClientRect().left-Fe(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),C.each({margin:"",padding:"",border:"Width"},function(i,o){C.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+p[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(C.cssHooks[i+o].set=lt)}),C.fn.extend({css:function(e,t){return f(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=We(e),i=t.length;a<i;a++)o[t[a]]=C.css(e,t[a],!1,r);return o}return void 0!==n?C.style(e,t,n):C.css(e,t)},e,t,1<arguments.length)}}),((C.Tween=a).prototype={constructor:a,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||C.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(C.cssNumber[n]?"":"px")},cur:function(){var e=a.propHooks[this.prop];return(e&&e.get?e:a.propHooks._default).get(this)},run:function(e){var t,n=a.propHooks[this.prop];return this.options.duration?this.pos=t=C.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),(n&&n.set?n:a.propHooks._default).set(this),this}}).init.prototype=a.prototype,(a.propHooks={_default:{get:function(e){return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(e=C.css(e.elem,e.prop,""))&&"auto"!==e?e:0},set:function(e){C.fx.step[e.prop]?C.fx.step[e.prop](e):1!==e.elem.nodeType||!C.cssHooks[e.prop]&&null==e.elem.style[ot(e.prop)]?e.elem[e.prop]=e.now:C.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=a.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},C.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},C.fx=a.prototype.init,C.fx.step={};var q,pt,L,dt=/^(?:toggle|show|hide)$/,ht=/queueHooks$/;function gt(){pt&&(!1===T.hidden&&w.requestAnimationFrame?w.requestAnimationFrame(gt):w.setTimeout(gt,C.fx.interval),C.fx.tick())}function yt(){return w.setTimeout(function(){q=void 0}),q=Date.now()}function mt(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=p[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function vt(e,t,n){for(var r,i=(H.tweeners[t]||[]).concat(H.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function H(i,e,t){var n,o,r,a,s,u,l,c=0,f=H.prefilters.length,p=C.Deferred().always(function(){delete d.elem}),d=function(){if(!o){for(var e=q||yt(),e=Math.max(0,h.startTime+h.duration-e),t=1-(e/h.duration||0),n=0,r=h.tweens.length;n<r;n++)h.tweens[n].run(t);if(p.notifyWith(i,[h,t,e]),t<1&&r)return e;r||p.notifyWith(i,[h,1,0]),p.resolveWith(i,[h])}return!1},h=p.promise({elem:i,props:C.extend({},e),opts:C.extend(!0,{specialEasing:{},easing:C.easing._default},t),originalProperties:e,originalOptions:t,startTime:q||yt(),duration:t.duration,tweens:[],createTween:function(e,t){t=C.Tween(i,h.opts,e,t,h.opts.specialEasing[e]||h.opts.easing);return h.tweens.push(t),t},stop:function(e){var t=0,n=e?h.tweens.length:0;if(!o){for(o=!0;t<n;t++)h.tweens[t].run(1);e?(p.notifyWith(i,[h,1,0]),p.resolveWith(i,[h,e])):p.rejectWith(i,[h,e])}return this}}),g=h.props,y=g,m=h.opts.specialEasing;for(r in y)if(s=m[a=x(r)],u=y[r],Array.isArray(u)&&(s=u[1],u=y[r]=u[0]),r!==a&&(y[a]=u,delete y[r]),(l=C.cssHooks[a])&&"expand"in l)for(r in u=l.expand(u),delete y[a],u)r in y||(y[r]=u[r],m[r]=s);else m[a]=s;for(;c<f;c++)if(n=H.prefilters[c].call(h,i,g,h.opts))return v(n.stop)&&(C._queueHooks(h.elem,h.opts.queue).stop=n.stop.bind(n)),n;return C.map(g,vt,h),v(h.opts.start)&&h.opts.start.call(i,h),h.progress(h.opts.progress).done(h.opts.done,h.opts.complete).fail(h.opts.fail).always(h.opts.always),C.fx.timer(C.extend(d,{elem:i,anim:h,queue:h.opts.queue})),h}C.Animation=C.extend(H,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return xe(n.elem,e,me.exec(t),n),n}]},tweener:function(e,t){for(var n,r=0,i=(e=v(e)?(t=e,["*"]):e.match(E)).length;r<i;r++)n=e[r],H.tweeners[n]=H.tweeners[n]||[],H.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c="width"in t||"height"in t,f=this,p={},d=e.style,h=e.nodeType&&ye(e),g=b.get(e,"fxshow");for(r in n.queue||(null==(a=C._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,f.always(function(){f.always(function(){a.unqueued--,C.queue(e,"fx").length||a.empty.fire()})})),t)if(i=t[r],dt.test(i)){if(delete t[r],o=o||"toggle"===i,i===(h?"hide":"show")){if("show"!==i||!g||void 0===g[r])continue;h=!0}p[r]=g&&g[r]||C.style(e,r)}if((u=!C.isEmptyObject(t))||!C.isEmptyObject(p))for(r in c&&1===e.nodeType&&(n.overflow=[d.overflow,d.overflowX,d.overflowY],null==(l=g&&g.display)&&(l=b.get(e,"display")),"none"===(c=C.css(e,"display"))&&(l?c=l:(A([e],!0),l=e.style.display||l,c=C.css(e,"display"),A([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===C.css(e,"float")&&(u||(f.done(function(){d.display=l}),null==l&&(c=d.display,l="none"===c?"":c)),d.display="inline-block")),n.overflow&&(d.overflow="hidden",f.always(function(){d.overflow=n.overflow[0],d.overflowX=n.overflow[1],d.overflowY=n.overflow[2]})),u=!1,p)u||(g?"hidden"in g&&(h=g.hidden):g=b.access(e,"fxshow",{display:l}),o&&(g.hidden=!h),h&&A([e],!0),f.done(function(){for(r in h||A([e]),b.remove(e,"fxshow"),p)C.style(e,r,p[r])})),u=vt(h?g[r]:0,r,f),r in g||(g[r]=u.start,h&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?H.prefilters.unshift(e):H.prefilters.push(e)}}),C.speed=function(e,t,n){var r=e&&"object"==typeof e?C.extend({},e):{complete:n||!n&&t||v(e)&&e,duration:e,easing:n&&t||t&&!v(t)&&t};return C.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in C.fx.speeds?r.duration=C.fx.speeds[r.duration]:r.duration=C.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){v(r.old)&&r.old.call(this),r.queue&&C.dequeue(this,r.queue)},r},C.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ye).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){function i(){var e=H(this,C.extend({},t),a);(o||b.get(this,"finish"))&&e.stop(!0)}var o=C.isEmptyObject(t),a=C.speed(e,n,r);return i.finish=i,o||!1===a.queue?this.each(i):this.queue(a.queue,i)},stop:function(i,e,o){function a(e){var t=e.stop;delete e.stop,t(o)}return"string"!=typeof i&&(o=e,e=i,i=void 0),e&&this.queue(i||"fx",[]),this.each(function(){var e=!0,t=null!=i&&i+"queueHooks",n=C.timers,r=b.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&ht.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||C.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||"fx"),this.each(function(){var e,t=b.get(this),n=t[a+"queue"],r=t[a+"queueHooks"],i=C.timers,o=n?n.length:0;for(t.finish=!0,C.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),C.each(["toggle","show","hide"],function(e,r){var i=C.fn[r];C.fn[r]=function(e,t,n){return null==e||"boolean"==typeof e?i.apply(this,arguments):this.animate(mt(r,!0),e,t,n)}}),C.each({slideDown:mt("show"),slideUp:mt("hide"),slideToggle:mt("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,r){C.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),C.timers=[],C.fx.tick=function(){var e,t=0,n=C.timers;for(q=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||C.fx.stop(),q=void 0},C.fx.timer=function(e){C.timers.push(e),C.fx.start()},C.fx.interval=13,C.fx.start=function(){pt||(pt=!0,gt())},C.fx.stop=function(){pt=null},C.fx.speeds={slow:600,fast:200,_default:400},C.fn.delay=function(r,e){return r=C.fx&&C.fx.speeds[r]||r,this.queue(e=e||"fx",function(e,t){var n=w.setTimeout(e,r);t.stop=function(){w.clearTimeout(n)}})},L=T.createElement("input"),e=T.createElement("select").appendChild(T.createElement("option")),L.type="checkbox",y.checkOn=""!==L.value,y.optSelected=e.selected,(L=T.createElement("input")).value="t",L.type="radio",y.radioValue="t"===L.value;var xt,bt=C.expr.attrHandle,wt=(C.fn.extend({attr:function(e,t){return f(this,C.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){C.removeAttr(this,e)})}}),C.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?C.prop(e,t,n):(1===o&&C.isXMLDoc(e)||(i=C.attrHooks[t.toLowerCase()]||(C.expr.match.bool.test(t)?xt:void 0)),void 0!==n?null===n?void C.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):!(i&&"get"in i&&null!==(r=i.get(e,t)))&&null==(r=C.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){var n;if(!y.radioValue&&"radio"===t&&u(e,"input"))return n=e.value,e.setAttribute("type",t),n&&(e.value=n),t}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(E);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),xt={set:function(e,t,n){return!1===t?C.removeAttr(e,n):e.setAttribute(n,n),n}},C.each(C.expr.match.bool.source.match(/\w+/g),function(e,t){var a=bt[t]||C.find.attr;bt[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=bt[o],bt[o]=r,r=null!=a(e,t,n)?o:null,bt[o]=i),r}}),/^(?:input|select|textarea|button)$/i),Tt=/^(?:a|area)$/i;function O(e){return(e.match(E)||[]).join(" ")}function P(e){return e.getAttribute&&e.getAttribute("class")||""}function Ct(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(E)||[]}C.fn.extend({prop:function(e,t){return f(this,C.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[C.propFix[e]||e]})}}),C.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&C.isXMLDoc(e)||(t=C.propFix[t]||t,i=C.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=C.find.attr(e,"tabindex");return t?parseInt(t,10):wt.test(e.nodeName)||Tt.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),y.optSelected||(C.propHooks.selected={get:function(e){e=e.parentNode;return e&&e.parentNode&&e.parentNode.selectedIndex,null},set:function(e){e=e.parentNode;e&&(e.selectedIndex,e.parentNode&&e.parentNode.selectedIndex)}}),C.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){C.propFix[this.toLowerCase()]=this}),C.fn.extend({addClass:function(t){var e,n,r,i,o,a;return v(t)?this.each(function(e){C(this).addClass(t.call(this,e,P(this)))}):(e=Ct(t)).length?this.each(function(){if(r=P(this),n=1===this.nodeType&&" "+O(r)+" "){for(o=0;o<e.length;o++)i=e[o],n.indexOf(" "+i+" ")<0&&(n+=i+" ");a=O(n),r!==a&&this.setAttribute("class",a)}}):this},removeClass:function(t){var e,n,r,i,o,a;return v(t)?this.each(function(e){C(this).removeClass(t.call(this,e,P(this)))}):arguments.length?(e=Ct(t)).length?this.each(function(){if(r=P(this),n=1===this.nodeType&&" "+O(r)+" "){for(o=0;o<e.length;o++){i=e[o];while(-1<n.indexOf(" "+i+" "))n=n.replace(" "+i+" "," ")}a=O(n),r!==a&&this.setAttribute("class",a)}}):this:this.attr("class","")},toggleClass:function(t,n){var e,r,i,o,a=typeof t,s="string"==a||Array.isArray(t);return v(t)?this.each(function(e){C(this).toggleClass(t.call(this,e,P(this),n),n)}):"boolean"==typeof n&&s?n?this.addClass(t):this.removeClass(t):(e=Ct(t),this.each(function(){if(s)for(o=C(this),i=0;i<e.length;i++)r=e[i],o.hasClass(r)?o.removeClass(r):o.addClass(r);else void 0!==t&&"boolean"!=a||((r=P(this))&&b.set(this,"__className__",r),this.setAttribute&&this.setAttribute("class",!r&&!1!==t&&b.get(this,"__className__")||""))}))},hasClass:function(e){var t,n=0,r=" "+e+" ";while(t=this[n++])if(1===t.nodeType&&-1<(" "+O(P(t))+" ").indexOf(r))return!0;return!1}});function Et(e){e.stopPropagation()}var St=/\r/g,kt=(C.fn.extend({val:function(t){var n,e,r,i=this[0];return arguments.length?(r=v(t),this.each(function(e){1===this.nodeType&&(null==(e=r?t.call(this,e,C(this).val()):t)?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=C.map(e,function(e){return null==e?"":e+""})),(n=C.valHooks[this.type]||C.valHooks[this.nodeName.toLowerCase()])&&"set"in n&&void 0!==n.set(this,e,"value")||(this.value=e))})):i?(n=C.valHooks[i.type]||C.valHooks[i.nodeName.toLowerCase()])&&"get"in n&&void 0!==(e=n.get(i,"value"))?e:"string"==typeof(e=i.value)?e.replace(St,""):null==e?"":e:void 0}}),C.extend({valHooks:{option:{get:function(e){var t=C.find.attr(e,"value");return null!=t?t:O(C.text(e))}},select:{get:function(e){for(var t,n=e.options,r=e.selectedIndex,i="select-one"===e.type,o=i?null:[],a=i?r+1:n.length,s=r<0?a:i?r:0;s<a;s++)if(((t=n[s]).selected||s===r)&&!t.disabled&&(!t.parentNode.disabled||!u(t.parentNode,"optgroup"))){if(t=C(t).val(),i)return t;o.push(t)}return o},set:function(e,t){var n,r,i=e.options,o=C.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<C.inArray(C.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),C.each(["radio","checkbox"],function(){C.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<C.inArray(C(e).val(),t)}},y.checkOn||(C.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),y.focusin="onfocusin"in w,/^(?:focusinfocus|focusoutblur)$/),At=(C.extend(C.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f=[n||T],p=_.call(e,"type")?e.type:e,d=_.call(e,"namespace")?e.namespace.split("."):[],h=c=o=n=n||T;if(3!==n.nodeType&&8!==n.nodeType&&!kt.test(p+C.event.triggered)&&(-1<p.indexOf(".")&&(p=(d=p.split(".")).shift(),d.sort()),s=p.indexOf(":")<0&&"on"+p,(e=e[C.expando]?e:new C.Event(p,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=d.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+d.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:C.makeArray(t,[e]),l=C.event.special[p]||{},r||!l.trigger||!1!==l.trigger.apply(n,t))){if(!r&&!l.noBubble&&!g(n)){for(a=l.delegateType||p,kt.test(a+p)||(h=h.parentNode);h;h=h.parentNode)f.push(h),o=h;o===(n.ownerDocument||T)&&f.push(o.defaultView||o.parentWindow||w)}i=0;while((h=f[i++])&&!e.isPropagationStopped())c=h,e.type=1<i?a:l.bindType||p,(u=(b.get(h,"events")||Object.create(null))[e.type]&&b.get(h,"handle"))&&u.apply(h,t),(u=s&&h[s])&&u.apply&&m(h)&&(e.result=u.apply(h,t),!1===e.result&&e.preventDefault());return e.type=p,r||e.isDefaultPrevented()||l._default&&!1!==l._default.apply(f.pop(),t)||!m(n)||s&&v(n[p])&&!g(n)&&((o=n[s])&&(n[s]=null),C.event.triggered=p,e.isPropagationStopped()&&c.addEventListener(p,Et),n[p](),e.isPropagationStopped()&&c.removeEventListener(p,Et),C.event.triggered=void 0,o&&(n[s]=o)),e.result}},simulate:function(e,t,n){n=C.extend(new C.Event,n,{type:e,isSimulated:!0});C.event.trigger(n,null,t)}}),C.fn.extend({trigger:function(e,t){return this.each(function(){C.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return C.event.trigger(e,t,n,!0)}}),y.focusin||C.each({focus:"focusin",blur:"focusout"},function(n,r){function i(e){C.event.simulate(r,e.target,C.event.fix(e))}C.event.special[r]={setup:function(){var e=this.ownerDocument||this.document||this,t=b.access(e,r);t||e.addEventListener(n,i,!0),b.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this.document||this,t=b.access(e,r)-1;t?b.access(e,r,t):(e.removeEventListener(n,i,!0),b.remove(e,r))}}}),w.location),Nt={guid:Date.now()},jt=/\?/,Dt=(C.parseXML=function(e){var t,n;if(!e||"string"!=typeof e)return null;try{t=(new w.DOMParser).parseFromString(e,"text/xml")}catch(e){}return n=t&&t.getElementsByTagName("parsererror")[0],t&&!n||C.error("Invalid XML: "+(n?C.map(n.childNodes,function(e){return e.textContent}).join("\n"):e)),t},/\[\]$/),qt=/\r?\n/g,Lt=/^(?:submit|button|image|reset|file)$/i,Ht=/^(?:input|select|textarea|keygen)/i;C.param=function(e,t){function n(e,t){t=v(t)?t():t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==t?"":t)}var r,i=[];if(null==e)return"";if(Array.isArray(e)||e.jquery&&!C.isPlainObject(e))C.each(e,function(){n(this.name,this.value)});else for(r in e)!function n(r,e,i,o){if(Array.isArray(e))C.each(e,function(e,t){i||Dt.test(r)?o(r,t):n(r+"["+("object"==typeof t&&null!=t?e:"")+"]",t,i,o)});else if(i||"object"!==h(e))o(r,e);else for(var t in e)n(r+"["+t+"]",e[t],i,o)}(r,e[r],t,n);return i.join("&")},C.fn.extend({serialize:function(){return C.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=C.prop(this,"elements");return e?C.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!C(this).is(":disabled")&&Ht.test(this.nodeName)&&!Lt.test(e)&&(this.checked||!we.test(e))}).map(function(e,t){var n=C(this).val();return null==n?null:Array.isArray(n)?C.map(n,function(e){return{name:t.name,value:e.replace(qt,"\r\n")}}):{name:t.name,value:n.replace(qt,"\r\n")}}).get()}});var Ot=/%20/g,Pt=/#.*$/,Rt=/([?&])_=[^&]*/,Mt=/^(.*?):[ \t]*([^\r\n]*)$/gm,It=/^(?:GET|HEAD)$/,Wt=/^\/\//,Ft={},$t={},Bt="*/".concat("*"),_t=T.createElement("a");function zt(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var n,r=0,i=e.toLowerCase().match(E)||[];if(v(t))while(n=i[r++])"+"===n[0]?(n=n.slice(1)||"*",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function Ut(t,r,i,o){var a={},s=t===$t;function u(e){var n;return a[e]=!0,C.each(t[e]||[],function(e,t){t=t(r,i,o);return"string"!=typeof t||s||a[t]?s?!(n=t):void 0:(r.dataTypes.unshift(t),u(t),!1)}),n}return u(r.dataTypes[0])||!a["*"]&&u("*")}function Xt(e,t){var n,r,i=C.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r=r||{})[n]=t[n]);return r&&C.extend(!0,e,r),e}_t.href=At.href,C.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:At.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(At.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Bt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":C.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Xt(Xt(e,C.ajaxSettings),t):Xt(C.ajaxSettings,e)},ajaxPrefilter:zt(Ft),ajaxTransport:zt($t),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0);var u,l,c,n,f,p,d,r,h=C.ajaxSetup({},t=t||{}),g=h.context||h,y=h.context&&(g.nodeType||g.jquery)?C(g):C.event,m=C.Deferred(),v=C.Callbacks("once memory"),x=h.statusCode||{},i={},o={},a="canceled",b={readyState:0,getResponseHeader:function(e){var t;if(p){if(!n){n={};while(t=Mt.exec(c))n[t[1].toLowerCase()+" "]=(n[t[1].toLowerCase()+" "]||[]).concat(t[2])}t=n[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return p?c:null},setRequestHeader:function(e,t){return null==p&&(e=o[e.toLowerCase()]=o[e.toLowerCase()]||e,i[e]=t),this},overrideMimeType:function(e){return null==p&&(h.mimeType=e),this},statusCode:function(e){if(e)if(p)b.always(e[b.status]);else for(var t in e)x[t]=[x[t],e[t]];return this},abort:function(e){e=e||a;return u&&u.abort(e),s(0,e),this}};if(m.promise(b),h.url=((e||h.url||At.href)+"").replace(Wt,At.protocol+"//"),h.type=t.method||t.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(E)||[""],null==h.crossDomain){e=T.createElement("a");try{e.href=h.url,e.href=e.href,h.crossDomain=_t.protocol+"//"+_t.host!=e.protocol+"//"+e.host}catch(e){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=C.param(h.data,h.traditional)),Ut(Ft,h,t,b),!p){for(r in(d=C.event&&h.global)&&0==C.active++&&C.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!It.test(h.type),l=h.url.replace(Pt,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(Ot,"+")):(e=h.url.slice(l.length),h.data&&(h.processData||"string"==typeof h.data)&&(l+=(jt.test(l)?"&":"?")+h.data,delete h.data),!1===h.cache&&(l=l.replace(Rt,"$1"),e=(jt.test(l)?"&":"?")+"_="+Nt.guid+++e),h.url=l+e),h.ifModified&&(C.lastModified[l]&&b.setRequestHeader("If-Modified-Since",C.lastModified[l]),C.etag[l]&&b.setRequestHeader("If-None-Match",C.etag[l])),(h.data&&h.hasContent&&!1!==h.contentType||t.contentType)&&b.setRequestHeader("Content-Type",h.contentType),b.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+Bt+"; q=0.01":""):h.accepts["*"]),h.headers)b.setRequestHeader(r,h.headers[r]);if(h.beforeSend&&(!1===h.beforeSend.call(g,b,h)||p))return b.abort();if(a="abort",v.add(h.complete),b.done(h.success),b.fail(h.error),u=Ut($t,h,t,b)){if(b.readyState=1,d&&y.trigger("ajaxSend",[b,h]),p)return b;h.async&&0<h.timeout&&(f=w.setTimeout(function(){b.abort("timeout")},h.timeout));try{p=!1,u.send(i,s)}catch(e){if(p)throw e;s(-1,e)}}else s(-1,"No Transport")}return b;function s(e,t,n,r){var i,o,a,s=t;p||(p=!0,f&&w.clearTimeout(f),u=void 0,c=r||"",b.readyState=0<e?4:0,r=200<=e&&e<300||304===e,n&&(a=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a=a||i}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(h,b,n)),!r&&-1<C.inArray("script",h.dataTypes)&&C.inArray("json",h.dataTypes)<0&&(h.converters["text script"]=function(){}),a=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e.throws)t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(h,a,b,r),r?(h.ifModified&&((n=b.getResponseHeader("Last-Modified"))&&(C.lastModified[l]=n),(n=b.getResponseHeader("etag"))&&(C.etag[l]=n)),204===e||"HEAD"===h.type?s="nocontent":304===e?s="notmodified":(s=a.state,i=a.data,r=!(o=a.error))):(o=s,!e&&s||(s="error",e<0&&(e=0))),b.status=e,b.statusText=(t||s)+"",r?m.resolveWith(g,[i,s,b]):m.rejectWith(g,[b,s,o]),b.statusCode(x),x=void 0,d&&y.trigger(r?"ajaxSuccess":"ajaxError",[b,h,r?i:o]),v.fireWith(g,[b,s]),d&&(y.trigger("ajaxComplete",[b,h]),--C.active||C.event.trigger("ajaxStop")))}},getJSON:function(e,t,n){return C.get(e,t,n,"json")},getScript:function(e,t){return C.get(e,void 0,t,"script")}}),C.each(["get","post"],function(e,i){C[i]=function(e,t,n,r){return v(t)&&(r=r||n,n=t,t=void 0),C.ajax(C.extend({url:e,type:i,dataType:r,data:t,success:n},C.isPlainObject(e)&&e))}}),C.ajaxPrefilter(function(e){for(var t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")}),C._evalUrl=function(e,t,n){return C.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){C.globalEval(e,t,n)}})},C.fn.extend({wrapAll:function(e){return this[0]&&(v(e)&&(e=e.call(this[0])),e=C(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&e.insertBefore(this[0]),e.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return v(n)?this.each(function(e){C(this).wrapInner(n.call(this,e))}):this.each(function(){var e=C(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=v(t);return this.each(function(e){C(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){C(this).replaceWith(this.childNodes)}),this}}),C.expr.pseudos.hidden=function(e){return!C.expr.pseudos.visible(e)},C.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},C.ajaxSettings.xhr=function(){try{return new w.XMLHttpRequest}catch(e){}};var Vt={0:200,1223:204},Gt=C.ajaxSettings.xhr(),Yt=(y.cors=!!Gt&&"withCredentials"in Gt,y.ajax=Gt=!!Gt,C.ajaxTransport(function(i){var o,a;if(y.cors||Gt&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,"abort"===e?r.abort():"error"===e?"number"!=typeof r.status?t(0,"error"):t(r.status,r.statusText):t(Vt[r.status]||r.status,r.statusText,"text"!==(r.responseType||"text")||"string"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o("error"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&w.setTimeout(function(){o&&a()})},o=o("abort");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),C.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),C.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return C.globalEval(e),e}}}),C.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),C.ajaxTransport("script",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=C("<script>").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),T.head.appendChild(r[0])},abort:function(){i&&i()}}}),[]),Qt=/(=)\?(?=&|$)|\?\?/,Jt=(C.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Yt.pop()||C.expando+"_"+Nt.guid++;return this[e]=!0,e}}),C.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Qt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Qt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Qt,"$1"+r):!1!==e.jsonp&&(e.url+=(jt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||C.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=w[r],w[r]=function(){o=arguments},n.always(function(){void 0===i?C(w).removeProp(r):w[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Yt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((o=T.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===o.childNodes.length),C.parseHTML=function(e,t,n){var r;return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=T.implementation.createHTMLDocument("")).createElement("base")).href=T.location.href,t.head.appendChild(r)):t=T),r=!n&&[],(n=J.exec(e))?[t.createElement(n[1])]:(n=ke([e],t,r),r&&r.length&&C(r).remove(),C.merge([],n.childNodes)))},C.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1<s&&(r=O(e.slice(s)),e=e.slice(0,s)),v(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),0<a.length&&C.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?C("<div>").append(C.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},C.expr.pseudos.animated=function(t){return C.grep(C.timers,function(e){return t===e.elem}).length},C.offset={setOffset:function(e,t,n){var r,i,o,a,s=C.css(e,"position"),u=C(e),l={};"static"===s&&(e.style.position="relative"),o=u.offset(),r=C.css(e,"top"),a=C.css(e,"left"),s=("absolute"===s||"fixed"===s)&&-1<(r+a).indexOf("auto")?(i=(s=u.position()).top,s.left):(i=parseFloat(r)||0,parseFloat(a)||0),null!=(t=v(t)?t.call(e,n,C.extend({},o)):t).top&&(l.top=t.top-o.top+i),null!=t.left&&(l.left=t.left-o.left+s),"using"in t?t.using.call(e,l):u.css(l)}},C.fn.extend({offset:function(t){var e,n;return arguments.length?void 0===t?this:this.each(function(e){C.offset.setOffset(this,t,e)}):(n=this[0])?n.getClientRects().length?(e=n.getBoundingClientRect(),n=n.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===C.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===C.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=C(e).offset()).top+=C.css(e,"borderTopWidth",!0),i.left+=C.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-C.css(r,"marginTop",!0),left:t.left-i.left-C.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===C.css(e,"position"))e=e.offsetParent;return e||S})}}),C.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;C.fn[t]=function(e){return f(this,function(e,t,n){var r;if(g(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),C.each(["top","left"],function(e,n){C.cssHooks[n]=tt(y.pixelPosition,function(e,t){if(t)return t=et(e,n),Ge.test(t)?C(e).position()[n]+"px":t})}),C.each({Height:"height",Width:"width"},function(a,s){C.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){C.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return f(this,function(e,t,n){var r;return g(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?C.css(e,t,i):C.style(e,t,n,i)},s,n?e:void 0,n)}})}),C.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){C.fn[t]=function(e){return this.on(t,e)}}),C.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),C.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){C.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}}),/^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g),Kt=(C.proxy=function(e,t){var n,r;if("string"==typeof t&&(r=e[t],t=e,e=r),v(e))return n=s.call(arguments,2),(r=function(){return e.apply(t||this,n.concat(s.call(arguments)))}).guid=e.guid=e.guid||C.guid++,r},C.holdReady=function(e){e?C.readyWait++:C.ready(!0)},C.isArray=Array.isArray,C.parseJSON=JSON.parse,C.nodeName=u,C.isFunction=v,C.isWindow=g,C.camelCase=x,C.type=h,C.now=Date.now,C.isNumeric=function(e){var t=C.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},C.trim=function(e){return null==e?"":(e+"").replace(Jt,"$1")},"function"==typeof define&&define.amd&&define("jquery",[],function(){return C}),w.jQuery),Zt=w.$;return C.noConflict=function(e){return w.$===C&&(w.$=Zt),e&&w.jQuery===C&&(w.jQuery=Kt),C},"undefined"==typeof R&&(w.jQuery=w.$=C),C}); /*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}S.fn=S.prototype={jquery:f,constructor:S,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=S.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return S.each(this,e)},map:function(n){return this.pushStack(S.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(S.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(S.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},S.extend=S.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(S.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||S.isPlainObject(n)?n:{},i=!1,a[t]=S.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},S.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=v.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){b(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(p(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},makeArray:function(e,t){var n=t||[];return null!=e&&(p(Object(e))?S.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(p(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:y}),"function"==typeof Symbol&&(S.fn[Symbol.iterator]=t[Symbol.iterator]),S.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var d=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,v,s,c,y,S="sizzle"+1*new Date,p=n.document,k=0,r=0,m=ue(),x=ue(),A=ue(),N=ue(),j=function(e,t){return e===t&&(l=!0),0},D={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",I="(?:\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",W="\\["+M+"*("+I+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+I+"))|)"+M+"*\\]",F=":("+I+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+W+")*)|.*)\\)|)",B=new RegExp(M+"+","g"),$=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=new RegExp("^"+M+"*,"+M+"*"),z=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="<a id='"+S+"'></a><select id='"+S+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0<se(t,C,null,[e]).length},se.contains=function(e,t){return(e.ownerDocument||e)!=C&&T(e),y(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!=C&&T(e);var n=b.attrHandle[t.toLowerCase()],r=n&&D.call(b.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==r?r:d.attributes||!E?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},se.escape=function(e){return(e+"").replace(re,ie)},se.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},se.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!d.detectDuplicates,u=!d.sortStable&&e.slice(0),e.sort(j),l){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return u=null,e},o=se.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=o(t);return n},(b=se.selectors={cacheLength:50,createPseudo:le,match:G,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace(B," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(h,e,t,g,v){var y="nth"!==h.slice(0,3),m="last"!==h.slice(-4),x="of-type"===e;return 1===g&&0===v?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=y!==m?"nextSibling":"previousSibling",c=e.parentNode,f=x&&e.nodeName.toLowerCase(),p=!n&&!x,d=!1;if(c){if(y){while(l){a=e;while(a=a[l])if(x?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l="only"===h&&!u&&"nextSibling"}return!0}if(u=[m?c.firstChild:c.lastChild],m&&p){d=(s=(r=(i=(o=(a=c)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1])&&r[2],a=s&&c.childNodes[s];while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if(1===a.nodeType&&++d&&a===e){i[h]=[k,s,d];break}}else if(p&&(d=s=(r=(i=(o=(a=e)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1]),!1===d)while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if((x?a.nodeName.toLowerCase()===f:1===a.nodeType)&&++d&&(p&&((i=(o=a[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[k,d]),a===e))break;return(d-=v)===g||d%g==0&&0<=d/g}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||se.error("unsupported pseudo: "+e);return a[S]?a(o):1<a.length?(t=[e,e,"",o],b.setFilters.hasOwnProperty(e.toLowerCase())?le(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=P(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:le(function(e){var r=[],i=[],s=f(e.replace($,"$1"));return s[S]?le(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:le(function(t){return function(e){return 0<se(t,e).length}}),contains:le(function(t){return t=t.replace(te,ne),function(e){return-1<(e.textContent||o(e)).indexOf(t)}}),lang:le(function(n){return V.test(n||"")||se.error("unsupported lang: "+n),n=n.replace(te,ne).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===a},focus:function(e){return e===C.activeElement&&(!C.hasFocus||C.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ve(function(){return[0]}),last:ve(function(e,t){return[t-1]}),eq:ve(function(e,t,n){return[n<0?n+t:n]}),even:ve(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:ve(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:ve(function(e,t,n){for(var r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:ve(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=de(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=he(e);function me(){}function xe(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function be(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&"parentNode"===c,p=r++;return e.first?function(e,t,n){while(e=e[u])if(1===e.nodeType||f)return s(e,t,n);return!1}:function(e,t,n){var r,i,o,a=[k,p];if(n){while(e=e[u])if((1===e.nodeType||f)&&s(e,t,n))return!0}else while(e=e[u])if(1===e.nodeType||f)if(i=(o=e[S]||(e[S]={}))[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===k&&r[1]===p)return a[2]=r[2];if((i[c]=a)[2]=s(e,t,n))return!0}return!1}}function we(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Te(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Ce(d,h,g,v,y,e){return v&&!v[S]&&(v=Ce(v)),y&&!y[S]&&(y=Ce(y,e)),le(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)se(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),f=!d||!e&&h?c:Te(c,s,d,n,r),p=g?y||(e?d:l||v)?[]:t:f;if(g&&g(f,p,n,r),v){i=Te(p,u),v(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(p[u[o]]=!(f[u[o]]=a))}if(e){if(y||d){if(y){i=[],o=p.length;while(o--)(a=p[o])&&i.push(f[o]=a);y(null,p=[],i,r)}o=p.length;while(o--)(a=p[o])&&-1<(i=y?P(e,a):s[o])&&(e[i]=!(t[i]=a))}}else p=Te(p===t?p.splice(l,p.length):p),y?y(null,t,p,r):H.apply(t,p)})}function Ee(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.relative[" "],s=o?1:0,u=be(function(e){return e===i},a,!0),l=be(function(e){return-1<P(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!==w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=b.relative[e[s].type])c=[be(we(c),t)];else{if((t=b.filter[e[s].type].apply(null,e[s].matches))[S]){for(n=++s;n<r;n++)if(b.relative[e[n].type])break;return Ce(1<s&&we(c),1<s&&xe(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace($,"$1"),t,s<n&&Ee(e.slice(s,n)),n<r&&Ee(e=e.slice(n)),n<r&&xe(e))}c.push(t)}return we(c)}return me.prototype=b.filters=b.pseudos,b.setFilters=new me,h=se.tokenize=function(e,t){var n,r,i,o,a,s,u,l=x[e+" "];if(l)return t?0:l.slice(0);a=e,s=[],u=b.preFilter;while(a){for(o in n&&!(r=_.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=z.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace($," ")}),a=a.slice(n.length)),b.filter)!(r=G[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?se.error(e):x(e,s).slice(0)},f=se.compile=function(e,t){var n,v,y,m,x,r,i=[],o=[],a=A[e+" "];if(!a){t||(t=h(e)),n=t.length;while(n--)(a=Ee(t[n]))[S]?i.push(a):o.push(a);(a=A(e,(v=o,m=0<(y=i).length,x=0<v.length,r=function(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG("*",i),h=k+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t==C||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){a=0,t||o.ownerDocument==C||(T(o),n=!E);while(s=v[a++])if(s(o,t||C,n)){r.push(o);break}i&&(k=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=y[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=q.call(r));f=Te(f)}H.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&se.uniqueSort(r)}return i&&(k=h,w=p),c},m?le(r):r))).selector=e}return a},g=se.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&h(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&E&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(te,ne),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=G.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],b.relative[s=a.type])break;if((u=b.find[s])&&(r=u(a.matches[0].replace(te,ne),ee.test(o[0].type)&&ye(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&xe(o)))return H.apply(n,r),n;break}}}return(l||f(e,c))(r,t,!E,n,!t||ee.test(e)&&ye(t.parentNode)||t),n},d.sortStable=S.split("").sort(j).join("")===S,d.detectDuplicates=!!l,T(),d.sortDetached=ce(function(e){return 1&e.compareDocumentPosition(C.createElement("fieldset"))}),ce(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||fe("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),d.attributes&&ce(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||fe("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ce(function(e){return null==e.getAttribute("disabled")})||fe(R,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),se}(C);S.find=d,S.expr=d.selectors,S.expr[":"]=S.expr.pseudos,S.uniqueSort=S.unique=d.uniqueSort,S.text=d.getText,S.isXMLDoc=d.isXML,S.contains=d.contains,S.escapeSelector=d.escape;var h=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&S(e).is(n))break;r.push(e)}return r},T=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},k=S.expr.match.needsContext;function A(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var N=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1<i.call(n,e)!==r}):S.filter(n,e,r)}S.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?S.find.matchesSelector(r,e)?[r]:[]:S.find.matches(e,S.grep(t,function(e){return 1===e.nodeType}))},S.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(S(e).filter(function(){for(t=0;t<r;t++)if(S.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)S.find(e,i[t],n);return 1<r?S.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&k.test(e)?S(e):e||[],!1).length}});var D,q=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(S.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&S(e);if(!k.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&S.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?S.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?i.call(S(e),this[0]):i.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(S.uniqueSort(S.merge(this.get(),S(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),S.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return h(e,"parentNode")},parentsUntil:function(e,t,n){return h(e,"parentNode",n)},next:function(e){return O(e,"nextSibling")},prev:function(e){return O(e,"previousSibling")},nextAll:function(e){return h(e,"nextSibling")},prevAll:function(e){return h(e,"previousSibling")},nextUntil:function(e,t,n){return h(e,"nextSibling",n)},prevUntil:function(e,t,n){return h(e,"previousSibling",n)},siblings:function(e){return T((e.parentNode||{}).firstChild,e)},children:function(e){return T(e.firstChild)},contents:function(e){return null!=e.contentDocument&&r(e.contentDocument)?e.contentDocument:(A(e,"template")&&(e=e.content||e),S.merge([],e.childNodes))}},function(r,i){S.fn[r]=function(e,t){var n=S.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=S.filter(t,n)),1<this.length&&(H[r]||S.uniqueSort(n),L.test(r)&&n.reverse()),this.pushStack(n)}});var P=/[^\x20\t\r\n\f]+/g;function R(e){return e}function M(e){throw e}function I(e,t,n,r){var i;try{e&&m(i=e.promise)?i.call(e).done(t).fail(n):e&&m(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}S.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},S.each(e.match(P)||[],function(e,t){n[t]=!0}),n):S.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:"")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){S.each(e,function(e,t){m(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&"string"!==w(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return S.each(arguments,function(e,t){var n;while(-1<(n=S.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<S.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t="",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=""),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},S.extend({Deferred:function(e){var o=[["notify","progress",S.Callbacks("memory"),S.Callbacks("memory"),2],["resolve","done",S.Callbacks("once memory"),S.Callbacks("once memory"),0,"resolved"],["reject","fail",S.Callbacks("once memory"),S.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},"catch":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return S.Deferred(function(r){S.each(o,function(e,t){var n=m(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&m(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,m(t)?s?t.call(e,l(u,o,R,s),l(u,o,M,s)):(u++,t.call(e,l(u,o,R,s),l(u,o,M,s),l(u,o,R,o.notifyWith))):(a!==R&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){S.Deferred.exceptionHook&&S.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==M&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(S.Deferred.getStackHook&&(t.stackTrace=S.Deferred.getStackHook()),C.setTimeout(t))}}return S.Deferred(function(e){o[0][3].add(l(0,e,m(r)?r:R,e.notifyWith)),o[1][3].add(l(0,e,m(t)?t:R)),o[2][3].add(l(0,e,m(n)?n:M))}).promise()},promise:function(e){return null!=e?S.extend(e,a):a}},s={};return S.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=s.call(arguments),o=S.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?s.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(I(e,o.done(a(t)).resolve,o.reject,!n),"pending"===o.state()||m(i[t]&&i[t].then)))return o.then();while(t--)I(i[t],a(t),o.reject);return o.promise()}});var W=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;S.Deferred.exceptionHook=function(e,t){C.console&&C.console.warn&&e&&W.test(e.name)&&C.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},S.readyException=function(e){C.setTimeout(function(){throw e})};var F=S.Deferred();function B(){E.removeEventListener("DOMContentLoaded",B),C.removeEventListener("load",B),S.ready()}S.fn.ready=function(e){return F.then(e)["catch"](function(e){S.readyException(e)}),this},S.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--S.readyWait:S.isReady)||(S.isReady=!0)!==e&&0<--S.readyWait||F.resolveWith(E,[S])}}),S.ready.then=F.then,"complete"===E.readyState||"loading"!==E.readyState&&!E.documentElement.doScroll?C.setTimeout(S.ready):(E.addEventListener("DOMContentLoaded",B),C.addEventListener("load",B));var $=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===w(n))for(s in i=!0,n)$(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,m(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(S(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},_=/^-ms-/,z=/-([a-z])/g;function U(e,t){return t.toUpperCase()}function X(e){return e.replace(_,"ms-").replace(z,U)}var V=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function G(){this.expando=S.expando+G.uid++}G.uid=1,G.prototype={cache:function(e){var t=e[this.expando];return t||(t={},V(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[X(t)]=n;else for(r in t)i[X(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][X(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(X):(t=X(t))in r?[t]:t.match(P)||[]).length;while(n--)delete r[t[n]]}(void 0===t||S.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!S.isEmptyObject(t)}};var Y=new G,Q=new G,J=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,K=/[A-Z]/g;function Z(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(K,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:J.test(i)?JSON.parse(i):i)}catch(e){}Q.set(e,t,n)}else n=void 0;return n}S.extend({hasData:function(e){return Q.hasData(e)||Y.hasData(e)},data:function(e,t,n){return Q.access(e,t,n)},removeData:function(e,t){Q.remove(e,t)},_data:function(e,t,n){return Y.access(e,t,n)},_removeData:function(e,t){Y.remove(e,t)}}),S.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=Q.get(o),1===o.nodeType&&!Y.get(o,"hasDataAttrs"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=X(r.slice(5)),Z(o,r,i[r]));Y.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof n?this.each(function(){Q.set(this,n)}):$(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=Q.get(o,n))?t:void 0!==(t=Z(o,n))?t:void 0;this.each(function(){Q.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){Q.remove(this,e)})}}),S.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Y.get(e,t),n&&(!r||Array.isArray(n)?r=Y.access(e,t,S.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=S.queue(e,t),r=n.length,i=n.shift(),o=S._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){S.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Y.get(e,n)||Y.access(e,n,{empty:S.Callbacks("once memory").add(function(){Y.remove(e,[t+"queue",n])})})}}),S.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?S.queue(this[0],t):void 0===n?this:this.each(function(){var e=S.queue(this,t,n);S._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&S.dequeue(this,t)})},dequeue:function(e){return this.each(function(){S.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=S.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=Y.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var ee=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,te=new RegExp("^(?:([+-])=|)("+ee+")([a-z%]*)$","i"),ne=["Top","Right","Bottom","Left"],re=E.documentElement,ie=function(e){return S.contains(e.ownerDocument,e)},oe={composed:!0};re.getRootNode&&(ie=function(e){return S.contains(e.ownerDocument,e)||e.getRootNode(oe)===e.ownerDocument});var ae=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&ie(e)&&"none"===S.css(e,"display")};function se(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return S.css(e,t,"")},u=s(),l=n&&n[3]||(S.cssNumber[t]?"":"px"),c=e.nodeType&&(S.cssNumber[t]||"px"!==l&&+u)&&te.exec(S.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)S.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,S.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var ue={};function le(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?("none"===n&&(l[c]=Y.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&ae(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=ue[s])||(o=a.body.appendChild(a.createElement(s)),u=S.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),ue[s]=u)))):"none"!==n&&(l[c]="none",Y.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}S.fn.extend({show:function(){return le(this,!0)},hide:function(){return le(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){ae(this)?S(this).show():S(this).hide()})}});var ce,fe,pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="<textarea>x</textarea>",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="<option></option>",y.option=!!ce.lastChild;var ge={thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n<r;n++)Y.set(e[n],"globalEval",!t||Y.get(t[n],"globalEval"))}ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td,y.option||(ge.optgroup=ge.option=[1,"<select multiple='multiple'>","</select>"]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===w(o))S.merge(p,o.nodeType?[o]:o);else if(me.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+S.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;S.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));f.textContent="",d=0;while(o=p[d++])if(r&&-1<S.inArray(o,r))i&&i.push(o);else if(l=ie(o),a=ve(f.appendChild(o),"script"),l&&ye(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}var be=/^([^.]*)(?:\.(.+)|)/;function we(){return!0}function Te(){return!1}function Ce(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ee(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ee(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Te;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return S().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=S.guid++)),e.each(function(){S.event.add(this,t,i,r,n)})}function Se(e,i,o){o?(Y.set(e,i,!1),S.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Y.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(S.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Y.set(this,i,r),t=o(this,i),this[i](),r!==(n=Y.get(this,i))||t?Y.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n&&n.value}else r.length&&(Y.set(this,i,{value:S.event.trigger(S.extend(r[0],S.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Y.get(e,i)&&S.event.add(e,i,we)}S.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.get(t);if(V(t)){n.handler&&(n=(o=n).handler,i=o.selector),i&&S.find.matchesSelector(re,i),n.guid||(n.guid=S.guid++),(u=v.events)||(u=v.events=Object.create(null)),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof S&&S.event.triggered!==e.type?S.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(P)||[""]).length;while(l--)d=g=(s=be.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=S.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=S.event.special[d]||{},c=S.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&S.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),S.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.hasData(e)&&Y.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(P)||[""]).length;while(l--)if(d=g=(s=be.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=S.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||S.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)S.event.remove(e,d+t[l],n,r,!0);S.isEmptyObject(u)&&Y.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),u=S.event.fix(e),l=(Y.get(this,"events")||Object.create(null))[u.type]||[],c=S.event.special[u.type]||{};for(s[0]=u,t=1;t<arguments.length;t++)s[t]=arguments[t];if(u.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,u)){a=S.event.handlers.call(this,u,l),t=0;while((i=a[t++])&&!u.isPropagationStopped()){u.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!u.isImmediatePropagationStopped())u.rnamespace&&!1!==o.namespace&&!u.rnamespace.test(o.namespace)||(u.handleObj=o,u.data=o.data,void 0!==(r=((S.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s))&&!1===(u.result=r)&&(u.preventDefault(),u.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,u),u.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<S(i,this).index(l):S.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(S.Event.prototype,t,{enumerable:!0,configurable:!0,get:m(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[S.expando]?e:new S.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Se(t,"click",we),!1},trigger:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Se(t,"click"),!0},_default:function(e){var t=e.target;return pe.test(t.type)&&t.click&&A(t,"input")&&Y.get(t,"click")||A(t,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},S.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},S.Event=function(e,t){if(!(this instanceof S.Event))return new S.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?we:Te,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&S.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[S.expando]=!0},S.Event.prototype={constructor:S.Event,isDefaultPrevented:Te,isPropagationStopped:Te,isImmediatePropagationStopped:Te,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=we,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=we,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=we,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},S.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:!0},S.event.addProp),S.each({focus:"focusin",blur:"focusout"},function(e,t){S.event.special[e]={setup:function(){return Se(this,e,Ce),!1},trigger:function(){return Se(this,e),!0},_default:function(){return!0},delegateType:t}}),S.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){S.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||S.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),S.fn.extend({on:function(e,t,n,r){return Ee(this,e,t,n,r)},one:function(e,t,n,r){return Ee(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,S(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=Te),this.each(function(){S.event.remove(this,e,n,t)})}});var ke=/<script|<style|<link/i,Ae=/checked\s*(?:[^=]|=\s*.checked.)/i,Ne=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n<r;n++)S.event.add(t,i,s[i][n]);Q.hasData(e)&&(o=Q.access(e),a=S.extend({},o),Q.set(t,a))}}function He(n,r,i,o){r=g(r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=m(d);if(h||1<f&&"string"==typeof d&&!y.checkClone&&Ae.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),He(t,r,i,o)});if(f&&(t=(e=xe(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=S.map(ve(e,"script"),De)).length;c<f;c++)u=e,c!==p&&(u=S.clone(u,!0,!0),s&&S.merge(a,ve(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,S.map(a,qe),c=0;c<s;c++)u=a[c],he.test(u.type||"")&&!Y.access(u,"globalEval")&&S.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?S._evalUrl&&!u.noModule&&S._evalUrl(u.src,{nonce:u.nonce||u.getAttribute("nonce")},l):b(u.textContent.replace(Ne,""),u,l))}return n}function Oe(e,t,n){for(var r,i=t?S.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||S.cleanData(ve(r)),r.parentNode&&(n&&ie(r)&&ye(ve(r,"script")),r.parentNode.removeChild(r));return e}S.extend({htmlPrefilter:function(e){return e},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=ie(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||S.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r<i;r++)s=o[r],u=a[r],void 0,"input"===(l=u.nodeName.toLowerCase())&&pe.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||ve(e),a=a||ve(c),r=0,i=o.length;r<i;r++)Le(o[r],a[r]);else Le(e,c);return 0<(a=ve(c,"script")).length&&ye(a,!f&&ve(e,"script")),c},cleanData:function(e){for(var t,n,r,i=S.event.special,o=0;void 0!==(n=e[o]);o++)if(V(n)){if(t=n[Y.expando]){if(t.events)for(r in t.events)i[r]?S.event.remove(n,r):S.removeEvent(n,r,t.handle);n[Y.expando]=void 0}n[Q.expando]&&(n[Q.expando]=void 0)}}}),S.fn.extend({detach:function(e){return Oe(this,e,!0)},remove:function(e){return Oe(this,e)},text:function(e){return $(this,function(e){return void 0===e?S.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return He(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||je(this,e).appendChild(e)})},prepend:function(){return He(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=je(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return He(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return He(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(S.cleanData(ve(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return S.clone(this,e,t)})},html:function(e){return $(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!ke.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=S.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(S.cleanData(ve(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return He(this,arguments,function(e){var t=this.parentNode;S.inArray(this,n)<0&&(S.cleanData(ve(this)),t&&t.replaceChild(e,this))},n)}}),S.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){S.fn[e]=function(e){for(var t,n=[],r=S(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),S(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var Pe=new RegExp("^("+ee+")(?!px)[a-z%]+$","i"),Re=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=C),t.getComputedStyle(e)},Me=function(e,t,n){var r,i,o={};for(i in t)o[i]=e.style[i],e.style[i]=t[i];for(i in r=n.call(e),t)e.style[i]=o[i];return r},Ie=new RegExp(ne.join("|"),"i");function We(e,t,n){var r,i,o,a,s=e.style;return(n=n||Re(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||ie(e)||(a=S.style(e,t)),!y.pixelBoxStyles()&&Pe.test(a)&&Ie.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function Fe(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(l){u.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",l.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",re.appendChild(u).appendChild(l);var e=C.getComputedStyle(l);n="1%"!==e.top,s=12===t(e.marginLeft),l.style.right="60%",o=36===t(e.right),r=36===t(e.width),l.style.position="absolute",i=12===t(l.offsetWidth/3),re.removeChild(u),l=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s,u=E.createElement("div"),l=E.createElement("div");l.style&&(l.style.backgroundClip="content-box",l.cloneNode(!0).style.backgroundClip="",y.clearCloneStyle="content-box"===l.style.backgroundClip,S.extend(y,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),s},scrollboxSize:function(){return e(),i},reliableTrDimensions:function(){var e,t,n,r;return null==a&&(e=E.createElement("table"),t=E.createElement("tr"),n=E.createElement("div"),e.style.cssText="position:absolute;left:-11111px;border-collapse:separate",t.style.cssText="border:1px solid",t.style.height="1px",n.style.height="9px",n.style.display="block",re.appendChild(e).appendChild(t).appendChild(n),r=C.getComputedStyle(t),a=parseInt(r.height,10)+parseInt(r.borderTopWidth,10)+parseInt(r.borderBottomWidth,10)===t.offsetHeight,re.removeChild(e)),a}}))}();var Be=["Webkit","Moz","ms"],$e=E.createElement("div").style,_e={};function ze(e){var t=S.cssProps[e]||_e[e];return t||(e in $e?e:_e[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=Be.length;while(n--)if((e=Be[n]+t)in $e)return e}(e)||e)}var Ue=/^(none|table(?!-c[ea]).+)/,Xe=/^--/,Ve={position:"absolute",visibility:"hidden",display:"block"},Ge={letterSpacing:"0",fontWeight:"400"};function Ye(e,t,n){var r=te.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function Qe(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=S.css(e,n+ne[a],!0,i)),r?("content"===n&&(u-=S.css(e,"padding"+ne[a],!0,i)),"margin"!==n&&(u-=S.css(e,"border"+ne[a]+"Width",!0,i))):(u+=S.css(e,"padding"+ne[a],!0,i),"padding"!==n?u+=S.css(e,"border"+ne[a]+"Width",!0,i):s+=S.css(e,"border"+ne[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function Je(e,t,n){var r=Re(e),i=(!y.boxSizingReliable()||n)&&"border-box"===S.css(e,"boxSizing",!1,r),o=i,a=We(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if(Pe.test(a)){if(!n)return a;a="auto"}return(!y.boxSizingReliable()&&i||!y.reliableTrDimensions()&&A(e,"tr")||"auto"===a||!parseFloat(a)&&"inline"===S.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===S.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+Qe(e,t,n||(i?"border":"content"),o,r,a)+"px"}function Ke(e,t,n,r,i){return new Ke.prototype.init(e,t,n,r,i)}S.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=We(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=X(t),u=Xe.test(t),l=e.style;if(u||(t=ze(s)),a=S.cssHooks[t]||S.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=te.exec(n))&&i[1]&&(n=se(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||u||(n+=i&&i[3]||(S.cssNumber[s]?"":"px")),y.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=X(t);return Xe.test(t)||(t=ze(s)),(a=S.cssHooks[t]||S.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=We(e,t,r)),"normal"===i&&t in Ge&&(i=Ge[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),S.each(["height","width"],function(e,u){S.cssHooks[u]={get:function(e,t,n){if(t)return!Ue.test(S.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?Je(e,u,n):Me(e,Ve,function(){return Je(e,u,n)})},set:function(e,t,n){var r,i=Re(e),o=!y.scrollboxSize()&&"absolute"===i.position,a=(o||n)&&"border-box"===S.css(e,"boxSizing",!1,i),s=n?Qe(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e["offset"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-Qe(e,u,"border",!1,i)-.5)),s&&(r=te.exec(t))&&"px"!==(r[3]||"px")&&(e.style[u]=t,t=S.css(e,u)),Ye(0,t,s)}}}),S.cssHooks.marginLeft=Fe(y.reliableMarginLeft,function(e,t){if(t)return(parseFloat(We(e,"marginLeft"))||e.getBoundingClientRect().left-Me(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),S.each({margin:"",padding:"",border:"Width"},function(i,o){S.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+ne[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(S.cssHooks[i+o].set=Ye)}),S.fn.extend({css:function(e,t){return $(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Re(e),i=t.length;a<i;a++)o[t[a]]=S.css(e,t[a],!1,r);return o}return void 0!==n?S.style(e,t,n):S.css(e,t)},e,t,1<arguments.length)}}),((S.Tween=Ke).prototype={constructor:Ke,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||S.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(S.cssNumber[n]?"":"px")},cur:function(){var e=Ke.propHooks[this.prop];return e&&e.get?e.get(this):Ke.propHooks._default.get(this)},run:function(e){var t,n=Ke.propHooks[this.prop];return this.options.duration?this.pos=t=S.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):Ke.propHooks._default.set(this),this}}).init.prototype=Ke.prototype,(Ke.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=S.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){S.fx.step[e.prop]?S.fx.step[e.prop](e):1!==e.elem.nodeType||!S.cssHooks[e.prop]&&null==e.elem.style[ze(e.prop)]?e.elem[e.prop]=e.now:S.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=Ke.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},S.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},S.fx=Ke.prototype.init,S.fx.step={};var Ze,et,tt,nt,rt=/^(?:toggle|show|hide)$/,it=/queueHooks$/;function ot(){et&&(!1===E.hidden&&C.requestAnimationFrame?C.requestAnimationFrame(ot):C.setTimeout(ot,S.fx.interval),S.fx.tick())}function at(){return C.setTimeout(function(){Ze=void 0}),Ze=Date.now()}function st(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=ne[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function ut(e,t,n){for(var r,i=(lt.tweeners[t]||[]).concat(lt.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function lt(o,e,t){var n,a,r=0,i=lt.prefilters.length,s=S.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=Ze||at(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:S.extend({},e),opts:S.extend(!0,{specialEasing:{},easing:S.easing._default},t),originalProperties:e,originalOptions:t,startTime:Ze||at(),duration:t.duration,tweens:[],createTween:function(e,t){var n=S.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=X(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=S.cssHooks[r])&&"expand"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=lt.prefilters[r].call(l,o,c,l.opts))return m(n.stop)&&(S._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return S.map(c,ut,l),m(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),S.fx.timer(S.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}S.Animation=S.extend(lt,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return se(n.elem,e,te.exec(t),n),n}]},tweener:function(e,t){m(e)?(t=e,e=["*"]):e=e.match(P);for(var n,r=0,i=e.length;r<i;r++)n=e[r],lt.tweeners[n]=lt.tweeners[n]||[],lt.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&ae(e),v=Y.get(e,"fxshow");for(r in n.queue||(null==(a=S._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,S.queue(e,"fx").length||a.empty.fire()})})),t)if(i=t[r],rt.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!v||void 0===v[r])continue;g=!0}d[r]=v&&v[r]||S.style(e,r)}if((u=!S.isEmptyObject(t))||!S.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=v&&v.display)&&(l=Y.get(e,"display")),"none"===(c=S.css(e,"display"))&&(l?c=l:(le([e],!0),l=e.style.display||l,c=S.css(e,"display"),le([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===S.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1,d)u||(v?"hidden"in v&&(g=v.hidden):v=Y.access(e,"fxshow",{display:l}),o&&(v.hidden=!g),g&&le([e],!0),p.done(function(){for(r in g||le([e]),Y.remove(e,"fxshow"),d)S.style(e,r,d[r])})),u=ut(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?lt.prefilters.unshift(e):lt.prefilters.push(e)}}),S.speed=function(e,t,n){var r=e&&"object"==typeof e?S.extend({},e):{complete:n||!n&&t||m(e)&&e,duration:e,easing:n&&t||t&&!m(t)&&t};return S.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in S.fx.speeds?r.duration=S.fx.speeds[r.duration]:r.duration=S.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){m(r.old)&&r.old.call(this),r.queue&&S.dequeue(this,r.queue)},r},S.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ae).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){var i=S.isEmptyObject(t),o=S.speed(e,n,r),a=function(){var e=lt(this,S.extend({},t),o);(i||Y.get(this,"finish"))&&e.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(i,e,o){var a=function(e){var t=e.stop;delete e.stop,t(o)};return"string"!=typeof i&&(o=e,e=i,i=void 0),e&&this.queue(i||"fx",[]),this.each(function(){var e=!0,t=null!=i&&i+"queueHooks",n=S.timers,r=Y.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&it.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||S.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||"fx"),this.each(function(){var e,t=Y.get(this),n=t[a+"queue"],r=t[a+"queueHooks"],i=S.timers,o=n?n.length:0;for(t.finish=!0,S.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),S.each(["toggle","show","hide"],function(e,r){var i=S.fn[r];S.fn[r]=function(e,t,n){return null==e||"boolean"==typeof e?i.apply(this,arguments):this.animate(st(r,!0),e,t,n)}}),S.each({slideDown:st("show"),slideUp:st("hide"),slideToggle:st("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,r){S.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),S.timers=[],S.fx.tick=function(){var e,t=0,n=S.timers;for(Ze=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||S.fx.stop(),Ze=void 0},S.fx.timer=function(e){S.timers.push(e),S.fx.start()},S.fx.interval=13,S.fx.start=function(){et||(et=!0,ot())},S.fx.stop=function(){et=null},S.fx.speeds={slow:600,fast:200,_default:400},S.fn.delay=function(r,e){return r=S.fx&&S.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=C.setTimeout(e,r);t.stop=function(){C.clearTimeout(n)}})},tt=E.createElement("input"),nt=E.createElement("select").appendChild(E.createElement("option")),tt.type="checkbox",y.checkOn=""!==tt.value,y.optSelected=nt.selected,(tt=E.createElement("input")).value="t",tt.type="radio",y.radioValue="t"===tt.value;var ct,ft=S.expr.attrHandle;S.fn.extend({attr:function(e,t){return $(this,S.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){S.removeAttr(this,e)})}}),S.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?S.prop(e,t,n):(1===o&&S.isXMLDoc(e)||(i=S.attrHooks[t.toLowerCase()]||(S.expr.match.bool.test(t)?ct:void 0)),void 0!==n?null===n?void S.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=S.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!y.radioValue&&"radio"===t&&A(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(P);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),ct={set:function(e,t,n){return!1===t?S.removeAttr(e,n):e.setAttribute(n,n),n}},S.each(S.expr.match.bool.source.match(/\w+/g),function(e,t){var a=ft[t]||S.find.attr;ft[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=ft[o],ft[o]=r,r=null!=a(e,t,n)?o:null,ft[o]=i),r}});var pt=/^(?:input|select|textarea|button)$/i,dt=/^(?:a|area)$/i;function ht(e){return(e.match(P)||[]).join(" ")}function gt(e){return e.getAttribute&&e.getAttribute("class")||""}function vt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(P)||[]}S.fn.extend({prop:function(e,t){return $(this,S.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[S.propFix[e]||e]})}}),S.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&S.isXMLDoc(e)||(t=S.propFix[t]||t,i=S.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=S.find.attr(e,"tabindex");return t?parseInt(t,10):pt.test(e.nodeName)||dt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),y.optSelected||(S.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),S.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){S.propFix[this.toLowerCase()]=this}),S.fn.extend({addClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){S(this).addClass(t.call(this,e,gt(this)))});if((e=vt(t)).length)while(n=this[u++])if(i=gt(n),r=1===n.nodeType&&" "+ht(i)+" "){a=0;while(o=e[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=ht(r))&&n.setAttribute("class",s)}return this},removeClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){S(this).removeClass(t.call(this,e,gt(this)))});if(!arguments.length)return this.attr("class","");if((e=vt(t)).length)while(n=this[u++])if(i=gt(n),r=1===n.nodeType&&" "+ht(i)+" "){a=0;while(o=e[a++])while(-1<r.indexOf(" "+o+" "))r=r.replace(" "+o+" "," ");i!==(s=ht(r))&&n.setAttribute("class",s)}return this},toggleClass:function(i,t){var o=typeof i,a="string"===o||Array.isArray(i);return"boolean"==typeof t&&a?t?this.addClass(i):this.removeClass(i):m(i)?this.each(function(e){S(this).toggleClass(i.call(this,e,gt(this),t),t)}):this.each(function(){var e,t,n,r;if(a){t=0,n=S(this),r=vt(i);while(e=r[t++])n.hasClass(e)?n.removeClass(e):n.addClass(e)}else void 0!==i&&"boolean"!==o||((e=gt(this))&&Y.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",e||!1===i?"":Y.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&-1<(" "+ht(gt(n))+" ").indexOf(t))return!0;return!1}});var yt=/\r/g;S.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=m(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,S(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=S.map(t,function(e){return null==e?"":e+""})),(r=S.valHooks[this.type]||S.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=S.valHooks[t.type]||S.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(yt,""):null==e?"":e:void 0}}),S.extend({valHooks:{option:{get:function(e){var t=S.find.attr(e,"value");return null!=t?t:ht(S.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!A(n.parentNode,"optgroup"))){if(t=S(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=S.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<S.inArray(S.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),S.each(["radio","checkbox"],function(){S.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<S.inArray(S(e).val(),t)}},y.checkOn||(S.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),y.focusin="onfocusin"in C;var mt=/^(?:focusinfocus|focusoutblur)$/,xt=function(e){e.stopPropagation()};S.extend(S.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,p=[n||E],d=v.call(e,"type")?e.type:e,h=v.call(e,"namespace")?e.namespace.split("."):[];if(o=f=a=n=n||E,3!==n.nodeType&&8!==n.nodeType&&!mt.test(d+S.event.triggered)&&(-1<d.indexOf(".")&&(d=(h=d.split(".")).shift(),h.sort()),u=d.indexOf(":")<0&&"on"+d,(e=e[S.expando]?e:new S.Event(d,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:S.makeArray(t,[e]),c=S.event.special[d]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!x(n)){for(s=c.delegateType||d,mt.test(s+d)||(o=o.parentNode);o;o=o.parentNode)p.push(o),a=o;a===(n.ownerDocument||E)&&p.push(a.defaultView||a.parentWindow||C)}i=0;while((o=p[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||d,(l=(Y.get(o,"events")||Object.create(null))[e.type]&&Y.get(o,"handle"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&V(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=d,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(p.pop(),t)||!V(n)||u&&m(n[d])&&!x(n)&&((a=n[u])&&(n[u]=null),S.event.triggered=d,e.isPropagationStopped()&&f.addEventListener(d,xt),n[d](),e.isPropagationStopped()&&f.removeEventListener(d,xt),S.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=S.extend(new S.Event,n,{type:e,isSimulated:!0});S.event.trigger(r,null,t)}}),S.fn.extend({trigger:function(e,t){return this.each(function(){S.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return S.event.trigger(e,t,n,!0)}}),y.focusin||S.each({focus:"focusin",blur:"focusout"},function(n,r){var i=function(e){S.event.simulate(r,e.target,S.event.fix(e))};S.event.special[r]={setup:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r);t||e.addEventListener(n,i,!0),Y.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r)-1;t?Y.access(e,r,t):(e.removeEventListener(n,i,!0),Y.remove(e,r))}}});var bt=C.location,wt={guid:Date.now()},Tt=/\?/;S.parseXML=function(e){var t,n;if(!e||"string"!=typeof e)return null;try{t=(new C.DOMParser).parseFromString(e,"text/xml")}catch(e){}return n=t&&t.getElementsByTagName("parsererror")[0],t&&!n||S.error("Invalid XML: "+(n?S.map(n.childNodes,function(e){return e.textContent}).join("\n"):e)),t};var Ct=/\[\]$/,Et=/\r?\n/g,St=/^(?:submit|button|image|reset|file)$/i,kt=/^(?:input|select|textarea|keygen)/i;function At(n,e,r,i){var t;if(Array.isArray(e))S.each(e,function(e,t){r||Ct.test(n)?i(n,t):At(n+"["+("object"==typeof t&&null!=t?e:"")+"]",t,r,i)});else if(r||"object"!==w(e))i(n,e);else for(t in e)At(n+"["+t+"]",e[t],r,i)}S.param=function(e,t){var n,r=[],i=function(e,t){var n=m(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!S.isPlainObject(e))S.each(e,function(){i(this.name,this.value)});else for(n in e)At(n,e[n],t,i);return r.join("&")},S.fn.extend({serialize:function(){return S.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=S.prop(this,"elements");return e?S.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!S(this).is(":disabled")&&kt.test(this.nodeName)&&!St.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=S(this).val();return null==n?null:Array.isArray(n)?S.map(n,function(e){return{name:t.name,value:e.replace(Et,"\r\n")}}):{name:t.name,value:n.replace(Et,"\r\n")}}).get()}});var Nt=/%20/g,jt=/#.*$/,Dt=/([?&])_=[^&]*/,qt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Lt=/^(?:GET|HEAD)$/,Ht=/^\/\//,Ot={},Pt={},Rt="*/".concat("*"),Mt=E.createElement("a");function It(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var n,r=0,i=e.toLowerCase().match(P)||[];if(m(t))while(n=i[r++])"+"===n[0]?(n=n.slice(1)||"*",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function Wt(t,i,o,a){var s={},u=t===Pt;function l(e){var r;return s[e]=!0,S.each(t[e]||[],function(e,t){var n=t(i,o,a);return"string"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s["*"]&&l("*")}function Ft(e,t){var n,r,i=S.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&S.extend(!0,e,r),e}Mt.href=bt.href,S.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:bt.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(bt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Rt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":S.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Ft(Ft(e,S.ajaxSettings),t):Ft(S.ajaxSettings,e)},ajaxPrefilter:It(Ot),ajaxTransport:It(Pt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,v=S.ajaxSetup({},t),y=v.context||v,m=v.context&&(y.nodeType||y.jquery)?S(y):S.event,x=S.Deferred(),b=S.Callbacks("once memory"),w=v.statusCode||{},a={},s={},u="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n){n={};while(t=qt.exec(p))n[t[1].toLowerCase()+" "]=(n[t[1].toLowerCase()+" "]||[]).concat(t[2])}t=n[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(v.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),v.url=((e||v.url||bt.href)+"").replace(Ht,bt.protocol+"//"),v.type=t.method||t.type||v.method||v.type,v.dataTypes=(v.dataType||"*").toLowerCase().match(P)||[""],null==v.crossDomain){r=E.createElement("a");try{r.href=v.url,r.href=r.href,v.crossDomain=Mt.protocol+"//"+Mt.host!=r.protocol+"//"+r.host}catch(e){v.crossDomain=!0}}if(v.data&&v.processData&&"string"!=typeof v.data&&(v.data=S.param(v.data,v.traditional)),Wt(Ot,v,t,T),h)return T;for(i in(g=S.event&&v.global)&&0==S.active++&&S.event.trigger("ajaxStart"),v.type=v.type.toUpperCase(),v.hasContent=!Lt.test(v.type),f=v.url.replace(jt,""),v.hasContent?v.data&&v.processData&&0===(v.contentType||"").indexOf("application/x-www-form-urlencoded")&&(v.data=v.data.replace(Nt,"+")):(o=v.url.slice(f.length),v.data&&(v.processData||"string"==typeof v.data)&&(f+=(Tt.test(f)?"&":"?")+v.data,delete v.data),!1===v.cache&&(f=f.replace(Dt,"$1"),o=(Tt.test(f)?"&":"?")+"_="+wt.guid+++o),v.url=f+o),v.ifModified&&(S.lastModified[f]&&T.setRequestHeader("If-Modified-Since",S.lastModified[f]),S.etag[f]&&T.setRequestHeader("If-None-Match",S.etag[f])),(v.data&&v.hasContent&&!1!==v.contentType||t.contentType)&&T.setRequestHeader("Content-Type",v.contentType),T.setRequestHeader("Accept",v.dataTypes[0]&&v.accepts[v.dataTypes[0]]?v.accepts[v.dataTypes[0]]+("*"!==v.dataTypes[0]?", "+Rt+"; q=0.01":""):v.accepts["*"]),v.headers)T.setRequestHeader(i,v.headers[i]);if(v.beforeSend&&(!1===v.beforeSend.call(y,T,v)||h))return T.abort();if(u="abort",b.add(v.complete),T.done(v.success),T.fail(v.error),c=Wt(Pt,v,t,T)){if(T.readyState=1,g&&m.trigger("ajaxSend",[T,v]),h)return T;v.async&&0<v.timeout&&(d=C.setTimeout(function(){T.abort("timeout")},v.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,"No Transport");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&C.clearTimeout(d),c=void 0,p=r||"",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(v,T,n)),!i&&-1<S.inArray("script",v.dataTypes)&&S.inArray("json",v.dataTypes)<0&&(v.converters["text script"]=function(){}),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(v,s,T,i),i?(v.ifModified&&((u=T.getResponseHeader("Last-Modified"))&&(S.lastModified[f]=u),(u=T.getResponseHeader("etag"))&&(S.etag[f]=u)),204===e||"HEAD"===v.type?l="nocontent":304===e?l="notmodified":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l="error",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+"",i?x.resolveWith(y,[o,l,T]):x.rejectWith(y,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?"ajaxSuccess":"ajaxError",[T,v,i?o:a]),b.fireWith(y,[T,l]),g&&(m.trigger("ajaxComplete",[T,v]),--S.active||S.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return S.get(e,t,n,"json")},getScript:function(e,t){return S.get(e,void 0,t,"script")}}),S.each(["get","post"],function(e,i){S[i]=function(e,t,n,r){return m(t)&&(r=r||n,n=t,t=void 0),S.ajax(S.extend({url:e,type:i,dataType:r,data:t,success:n},S.isPlainObject(e)&&e))}}),S.ajaxPrefilter(function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")}),S._evalUrl=function(e,t,n){return S.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){S.globalEval(e,t,n)}})},S.fn.extend({wrapAll:function(e){var t;return this[0]&&(m(e)&&(e=e.call(this[0])),t=S(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return m(n)?this.each(function(e){S(this).wrapInner(n.call(this,e))}):this.each(function(){var e=S(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=m(t);return this.each(function(e){S(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){S(this).replaceWith(this.childNodes)}),this}}),S.expr.pseudos.hidden=function(e){return!S.expr.pseudos.visible(e)},S.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},S.ajaxSettings.xhr=function(){try{return new C.XMLHttpRequest}catch(e){}};var Bt={0:200,1223:204},$t=S.ajaxSettings.xhr();y.cors=!!$t&&"withCredentials"in $t,y.ajax=$t=!!$t,S.ajaxTransport(function(i){var o,a;if(y.cors||$t&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,"abort"===e?r.abort():"error"===e?"number"!=typeof r.status?t(0,"error"):t(r.status,r.statusText):t(Bt[r.status]||r.status,r.statusText,"text"!==(r.responseType||"text")||"string"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o("error"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&C.setTimeout(function(){o&&a()})},o=o("abort");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),S.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),S.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return S.globalEval(e),e}}}),S.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),S.ajaxTransport("script",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=S("<script>").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1<s&&(r=ht(e.slice(s)),e=e.slice(0,s)),m(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),0<a.length&&S.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?S("<div>").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}});var Xt=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;S.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),m(e))return r=s.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(s.call(arguments)))}).guid=e.guid=e.guid||S.guid++,i},S.holdReady=function(e){e?S.readyWait++:S.ready(!0)},S.isArray=Array.isArray,S.parseJSON=JSON.parse,S.nodeName=A,S.isFunction=m,S.isWindow=x,S.camelCase=X,S.type=w,S.now=Date.now,S.isNumeric=function(e){var t=S.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},S.trim=function(e){return null==e?"":(e+"").replace(Xt,"")},"function"==typeof define&&define.amd&&define("jquery",[],function(){return S});var Vt=C.jQuery,Gt=C.$;return S.noConflict=function(e){return C.$===S&&(C.$=Gt),e&&C.jQuery===S&&(C.jQuery=Vt),S},"undefined"==typeof e&&(C.jQuery=C.$=S),S});
-
-
-
@@ -0,0 +1,1 @@!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=4)}({4:function(e,t,r){}});
-
-
-
@@ -1,266 +1,1 @@// jQuery is included via the sphinxcontrib-jquery extension that we depend on var jQuery = (typeof(window) != 'undefined') ? window.jQuery : require('jquery'); // Sphinx theme nav state function ThemeNav () { var nav = { navBar: null, win: null, winScroll: false, winResize: false, linkScroll: false, winPosition: 0, winHeight: null, docHeight: null, isRunning: false }; nav.enable = function (withStickyNav) { var self = this; // TODO this can likely be removed once the theme javascript is broken // out from the RTD assets. This just ensures old projects that are // calling `enable()` get the sticky menu on by default. All other cals // to `enable` should include an argument for enabling the sticky menu. if (typeof(withStickyNav) == 'undefined') { withStickyNav = true; } if (self.isRunning) { // Only allow enabling nav logic once return; } self.isRunning = true; jQuery(function ($) { self.init($); self.reset(); self.win.on('hashchange', self.reset); if (withStickyNav) { // Set scroll monitor self.win.on('scroll', function () { if (!self.linkScroll) { if (!self.winScroll) { self.winScroll = true; requestAnimationFrame(function() { self.onScroll(); }); } } }); } // Set resize monitor self.win.on('resize', function () { if (!self.winResize) { self.winResize = true; requestAnimationFrame(function() { self.onResize(); }); } }); self.onResize(); }); }; // TODO remove this with a split in theme and Read the Docs JS logic as // well, it's only here to support 0.3.0 installs of our theme. nav.enableSticky = function() { this.enable(true); }; nav.init = function ($) { var doc = $(document), self = this; this.navBar = $('div.wy-side-scroll:first'); this.win = $(window); // Set up javascript UX bits $(document) // Shift nav in mobile when clicking the menu. .on('click', "[data-toggle='wy-nav-top']", function() { $("[data-toggle='wy-nav-shift']").toggleClass("shift"); $("[data-toggle='rst-versions']").toggleClass("shift"); }) // Nav menu link click operations .on('click', ".wy-menu-vertical .current ul li a", function() { var target = $(this); // Close menu when you click a link. $("[data-toggle='wy-nav-shift']").removeClass("shift"); $("[data-toggle='rst-versions']").toggleClass("shift"); // Handle dynamic display of l3 and l4 nav lists self.toggleCurrent(target); self.hashChange(); }) .on('click', "[data-toggle='rst-current-version']", function() { $("[data-toggle='rst-versions']").toggleClass("shift-up"); }) // Make tables responsive $("table.docutils:not(.field-list,.footnote,.citation)") .wrap("<div class='wy-table-responsive'></div>"); // Add extra class to responsive tables that contain // footnotes or citations so that we can target them for styling $("table.docutils.footnote") .wrap("<div class='wy-table-responsive footnote'></div>"); $("table.docutils.citation") .wrap("<div class='wy-table-responsive citation'></div>"); // Add expand links to all parents of nested ul $('.wy-menu-vertical ul').not('.simple').siblings('a').each(function () { var link = $(this); expand = $('<button class="toctree-expand" title="Open/close menu"></button>'); expand.on('click', function (ev) { self.toggleCurrent(link); ev.stopPropagation(); return false; }); link.prepend(expand); }); }; nav.reset = function () { // Get anchor from URL and open up nested nav var anchor = encodeURI(window.location.hash) || '#'; try { var vmenu = $('.wy-menu-vertical'); var link = vmenu.find('[href="' + anchor + '"]'); if (link.length === 0) { // this link was not found in the sidebar. // Find associated id element, then its closest section // in the document and try with that one. var id_elt = $('.document [id="' + anchor.substring(1) + '"]'); var closest_section = id_elt.closest('div.section'); link = vmenu.find('[href="#' + closest_section.attr("id") + '"]'); if (link.length === 0) { // still not found in the sidebar. fall back to main section link = vmenu.find('[href="#"]'); } } // If we found a matching link then reset current and re-apply // otherwise retain the existing match if (link.length > 0) { $('.wy-menu-vertical .current') .removeClass('current') .attr('aria-expanded','false'); link.addClass('current') .attr('aria-expanded','true'); link.closest('li.toctree-l1') .parent() .addClass('current') .attr('aria-expanded','true'); for (let i = 1; i <= 10; i++) { link.closest('li.toctree-l' + i) .addClass('current') .attr('aria-expanded','true'); } link[0].scrollIntoView(); } } catch (err) { console.log("Error expanding nav for anchor", err); } }; nav.onScroll = function () { this.winScroll = false; var newWinPosition = this.win.scrollTop(), winBottom = newWinPosition + this.winHeight, navPosition = this.navBar.scrollTop(), newNavPosition = navPosition + (newWinPosition - this.winPosition); if (newWinPosition < 0 || winBottom > this.docHeight) { return; } this.navBar.scrollTop(newNavPosition); this.winPosition = newWinPosition; }; nav.onResize = function () { this.winResize = false; this.winHeight = this.win.height(); this.docHeight = $(document).height(); }; nav.hashChange = function () { this.linkScroll = true; this.win.one('hashchange', function () { this.linkScroll = false; }); }; nav.toggleCurrent = function (elem) { var parent_li = elem.closest('li'); parent_li .siblings('li.current') .removeClass('current') .attr('aria-expanded','false'); parent_li .siblings() .find('li.current') .removeClass('current') .attr('aria-expanded','false'); var children = parent_li.find('> ul li'); // Don't toggle terminal elements. if (children.length) { children .removeClass('current') .attr('aria-expanded','false'); parent_li .toggleClass('current') .attr('aria-expanded', function(i, old) { return old == 'true' ? 'false' : 'true'; }); } } return nav; }; _ThemeNav = ThemeNav(); if (typeof(window) != 'undefined') { window.SphinxRtdTheme = { Navigation: _ThemeNav, // TODO remove this once static assets are split up between the theme // and Read the Docs. For now, this patches 0.3.0 to be backwards // compatible with a pre-0.3.0 layout.html StickyNav: _ThemeNav, }; } // requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel // https://gist.github.com/paulirish/1579671 // MIT license (function() { var lastTime = 0; var vendors = ['ms', 'moz', 'webkit', 'o']; for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; } if (!window.requestAnimationFrame) window.requestAnimationFrame = function(callback, element) { var currTime = new Date().getTime(); var timeToCall = Math.max(0, 16 - (currTime - lastTime)); var id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall); lastTime = currTime + timeToCall; return id; }; if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function(id) { clearTimeout(id); }; }()); !function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("<div class='wy-table-responsive'></div>"),n("table.docutils.footnote").wrap("<div class='wy-table-responsive footnote'></div>"),n("table.docutils.citation").wrap("<div class='wy-table-responsive citation'></div>"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n('<button class="toctree-expand" title="Open/close menu"></button>'),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t<e.length&&!window.requestAnimationFrame;++t)window.requestAnimationFrame=window[e[t]+"RequestAnimationFrame"],window.cancelAnimationFrame=window[e[t]+"CancelAnimationFrame"]||window[e[t]+"CancelRequestAnimationFrame"];window.requestAnimationFrame||(window.requestAnimationFrame=function(e,t){var i=(new Date).getTime(),o=Math.max(0,16-(i-n)),r=window.setTimeout((function(){e(i+o)}),o);return n=i+o,r}),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(n){clearTimeout(n)})}()}).call(window)},function(n,e){n.exports=jQuery},function(n,e,t){}]);
-
-
-
@@ -0,0 +1,228 @@const themeFlyoutDisplay = "hidden"; const themeVersionSelector = true; const themeLanguageSelector = true; if (themeFlyoutDisplay === "attached") { function renderLanguages(config) { if (!config.projects.translations.length) { return ""; } // Insert the current language to the options on the selector let languages = config.projects.translations.concat(config.projects.current); languages = languages.sort((a, b) => a.language.name.localeCompare(b.language.name)); const languagesHTML = ` <dl> <dt>Languages</dt> ${languages .map( (translation) => ` <dd ${translation.slug == config.projects.current.slug ? 'class="rtd-current-item"' : ""}> <a href="${translation.urls.documentation}">${translation.language.code}</a> </dd> `, ) .join("\n")} </dl> `; return languagesHTML; } function renderVersions(config) { if (!config.versions.active.length) { return ""; } const versionsHTML = ` <dl> <dt>Versions</dt> ${config.versions.active .map( (version) => ` <dd ${version.slug === config.versions.current.slug ? 'class="rtd-current-item"' : ""}> <a href="${version.urls.documentation}">${version.slug}</a> </dd> `, ) .join("\n")} </dl> `; return versionsHTML; } function renderDownloads(config) { if (!Object.keys(config.versions.current.downloads).length) { return ""; } const downloadsNameDisplay = { pdf: "PDF", epub: "Epub", htmlzip: "HTML", }; const downloadsHTML = ` <dl> <dt>Downloads</dt> ${Object.entries(config.versions.current.downloads) .map( ([name, url]) => ` <dd> <a href="${url}">${downloadsNameDisplay[name]}</a> </dd> `, ) .join("\n")} </dl> `; return downloadsHTML; } document.addEventListener("readthedocs-addons-data-ready", function (event) { const config = event.detail.data(); const flyout = ` <div class="rst-versions" data-toggle="rst-versions" role="note"> <span class="rst-current-version" data-toggle="rst-current-version"> <span class="fa fa-book"> Read the Docs</span> v: ${config.versions.current.slug} <span class="fa fa-caret-down"></span> </span> <div class="rst-other-versions"> <div class="injected"> ${renderLanguages(config)} ${renderVersions(config)} ${renderDownloads(config)} <dl> <dt>On Read the Docs</dt> <dd> <a href="${config.projects.current.urls.home}">Project Home</a> </dd> <dd> <a href="${config.projects.current.urls.builds}">Builds</a> </dd> <dd> <a href="${config.projects.current.urls.downloads}">Downloads</a> </dd> </dl> <dl> <dt>Search</dt> <dd> <form id="flyout-search-form"> <input class="wy-form" type="text" name="q" aria-label="Search docs" placeholder="Search docs" /> </form> </dd> </dl> <hr /> <small> <span>Hosted by <a href="https://about.readthedocs.org/?utm_source=&utm_content=flyout">Read the Docs</a></span> </small> </div> </div> `; // Inject the generated flyout into the body HTML element. document.body.insertAdjacentHTML("beforeend", flyout); // Trigger the Read the Docs Addons Search modal when clicking on the "Search docs" input from inside the flyout. document .querySelector("#flyout-search-form") .addEventListener("focusin", () => { const event = new CustomEvent("readthedocs-search-show"); document.dispatchEvent(event); }); }) } if (themeLanguageSelector || themeVersionSelector) { function onSelectorSwitch(event) { const option = event.target.selectedIndex; const item = event.target.options[option]; window.location.href = item.dataset.url; } document.addEventListener("readthedocs-addons-data-ready", function (event) { const config = event.detail.data(); const versionSwitch = document.querySelector( "div.switch-menus > div.version-switch", ); if (themeVersionSelector) { let versions = config.versions.active; if (config.versions.current.hidden || config.versions.current.type === "external") { versions.unshift(config.versions.current); } const versionSelect = ` <select> ${versions .map( (version) => ` <option value="${version.slug}" ${config.versions.current.slug === version.slug ? 'selected="selected"' : ""} data-url="${version.urls.documentation}"> ${version.slug} </option>`, ) .join("\n")} </select> `; versionSwitch.innerHTML = versionSelect; versionSwitch.firstElementChild.addEventListener("change", onSelectorSwitch); } const languageSwitch = document.querySelector( "div.switch-menus > div.language-switch", ); if (themeLanguageSelector) { if (config.projects.translations.length) { // Add the current language to the options on the selector let languages = config.projects.translations.concat( config.projects.current, ); languages = languages.sort((a, b) => a.language.name.localeCompare(b.language.name), ); const languageSelect = ` <select> ${languages .map( (language) => ` <option value="${language.language.code}" ${config.projects.current.slug === language.slug ? 'selected="selected"' : ""} data-url="${language.urls.documentation}"> ${language.language.name} </option>`, ) .join("\n")} </select> `; languageSwitch.innerHTML = languageSelect; languageSwitch.firstElementChild.addEventListener("change", onSelectorSwitch); } else { languageSwitch.remove(); } } }); } document.addEventListener("readthedocs-addons-data-ready", function (event) { // Trigger the Read the Docs Addons Search modal when clicking on "Search docs" input from the topnav. document .querySelector("[role='search'] input") .addEventListener("focusin", () => { const event = new CustomEvent("readthedocs-search-show"); document.dispatchEvent(event); }); });
-
-
-
@@ -1,19 +1,12 @@/* * language_data.js * ~~~~~~~~~~~~~~~~ * * This script contains the language-specific data used by searchtools.js, * namely the list of stopwords, stemmer, scorer and splitter. * * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; /* Non-minified version is copied as a separate JS file, is available */ /* Non-minified version is copied as a separate JS file, if available */ /** * Porter Stemmer
-
-
-
@@ -1,12 +1,5 @@/* * searchtools.js * ~~~~~~~~~~~~~~~~ * * Sphinx JavaScript utilities for the full-text search. * * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ "use strict";
-
@@ -20,7 +13,7 @@ // The function takes a result array [docname, title, anchor, descr, score, filename]// and returns the new score. /* score: result => { const [docname, title, anchor, descr, score, filename] = result const [docname, title, anchor, descr, score, filename, kind] = result return score }, */
-
@@ -47,6 +40,14 @@ partialTerm: 2,}; } // Global search result kind enum, used by themes to style search results. class SearchResultKind { static get index() { return "index"; } static get object() { return "object"; } static get text() { return "text"; } static get title() { return "title"; } } const _removeChildren = (element) => { while (element && element.lastChild) element.removeChild(element.lastChild); };
-
@@ -62,12 +63,15 @@ const docBuilder = DOCUMENTATION_OPTIONS.BUILDER;const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; const contentRoot = document.documentElement.dataset.content_root ?? DOCUMENTATION_OPTIONS.URL_ROOT; const contentRoot = document.documentElement.dataset.content_root; const [docName, title, anchor, descr, score, _filename] = item; const [docName, title, anchor, descr, score, _filename, kind] = item; let listItem = document.createElement("li"); // Add a class representing the item's type: // can be used by a theme's CSS selector for styling // See SearchResultKind for the class names. listItem.classList.add(`kind-${kind}`); let requestUrl; let linkUrl; if (docBuilder === "dirhtml") {
-
@@ -100,7 +104,7 @@ .then((responseData) => responseData.text()).then((data) => { if (data) listItem.appendChild( Search.makeSearchSummary(data, searchTerms) Search.makeSearchSummary(data, searchTerms, anchor) ); // highlight search terms in the summary if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js
-
@@ -116,9 +120,11 @@ Search.status.innerText = Documentation.gettext("Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." ); else Search.status.innerText = _( `Search finished, found ${resultCount} page(s) matching the search query.` ); Search.status.innerText = Documentation.ngettext( "Search finished, found one page matching the search query.", "Search finished, found ${resultCount} pages matching the search query.", resultCount, ).replace('${resultCount}', resultCount); }; const _displayNextItem = ( results,
-
@@ -138,6 +144,22 @@ }// search finished, update title and status message else _finishSearch(resultCount); }; // Helper function used by query() to order search results. // Each input is an array of [docname, title, anchor, descr, score, filename, kind]. // Order the results by score (in opposite order of appearance, since the // `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. const _orderResultsByScoreThenName = (a, b) => { const leftScore = a[4]; const rightScore = b[4]; if (leftScore === rightScore) { // same score: sort alphabetically const leftTitle = a[1].toLowerCase(); const rightTitle = b[1].toLowerCase(); if (leftTitle === rightTitle) return 0; return leftTitle > rightTitle ? -1 : 1; // inverted is intentional } return leftScore > rightScore ? 1 : -1; }; /** * Default splitQuery function. Can be overridden in ``sphinx.search`` with a
-
@@ -161,13 +183,26 @@ _index: null,_queued_query: null, _pulse_status: -1, htmlToText: (htmlString) => { htmlToText: (htmlString, anchor) => { const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() }); for (const removalQuery of [".headerlink", "script", "style"]) { htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); } if (anchor) { const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); if (anchorContent) return anchorContent.textContent; console.warn( `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` ); } // if anchor not specified or not found, fall back to main content const docContent = htmlElement.querySelector('[role="main"]'); if (docContent !== undefined) return docContent.textContent; if (docContent) return docContent.textContent; console.warn( "Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template." "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." ); return ""; },
-
@@ -220,6 +255,7 @@ const searchSummary = document.createElement("p");searchSummary.classList.add("search-summary"); searchSummary.innerText = ""; const searchList = document.createElement("ul"); searchList.setAttribute("role", "list"); searchList.classList.add("search"); const out = document.getElementById("search-results");
-
@@ -240,16 +276,7 @@ if (Search.hasIndex()) Search.query(query);else Search.deferQuery(query); }, /** * execute search (requires search index to be loaded) */ query: (query) => { const filenames = Search._index.filenames; const docNames = Search._index.docnames; const titles = Search._index.titles; const allTitles = Search._index.alltitles; const indexEntries = Search._index.indexentries; _parseQuery: (query) => { // stem the search terms and add them to the correct list const stemmer = new Stemmer(); const searchTerms = new Set();
-
@@ -285,22 +312,40 @@ // console.debug("SEARCH: searching for:");// console.info("required: ", [...searchTerms]); // console.info("excluded: ", [...excludedTerms]); // array of [docname, title, anchor, descr, score, filename] let results = []; return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; }, /** * execute search (requires search index to be loaded) */ _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { const filenames = Search._index.filenames; const docNames = Search._index.docnames; const titles = Search._index.titles; const allTitles = Search._index.alltitles; const indexEntries = Search._index.indexentries; // Collect multiple result groups to be sorted separately and then ordered. // Each is an array of [docname, title, anchor, descr, score, filename, kind]. const normalResults = []; const nonMainIndexResults = []; _removeChildren(document.getElementById("search-progress")); const queryLower = query.toLowerCase(); const queryLower = query.toLowerCase().trim(); for (const [title, foundTitles] of Object.entries(allTitles)) { if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) { if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { for (const [file, id] of foundTitles) { let score = Math.round(100 * queryLower.length / title.length) results.push([ const score = Math.round(Scorer.title * queryLower.length / title.length); const boost = titles[file] === title ? 1 : 0; // add a boost for document titles normalResults.push([ docNames[file], titles[file] !== title ? `${titles[file]} > ${title}` : title, id !== null ? "#" + id : "", null, score, score + boost, filenames[file], SearchResultKind.title, ]); } }
-
@@ -309,46 +354,48 @@// search for explicit entries in index directives for (const [entry, foundEntries] of Object.entries(indexEntries)) { if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { for (const [file, id] of foundEntries) { let score = Math.round(100 * queryLower.length / entry.length) results.push([ for (const [file, id, isMain] of foundEntries) { const score = Math.round(100 * queryLower.length / entry.length); const result = [ docNames[file], titles[file], id ? "#" + id : "", null, score, filenames[file], ]); SearchResultKind.index, ]; if (isMain) { normalResults.push(result); } else { nonMainIndexResults.push(result); } } } } // lookup as object objectTerms.forEach((term) => results.push(...Search.performObjectSearch(term, objectTerms)) normalResults.push(...Search.performObjectSearch(term, objectTerms)) ); // lookup as search terms in fulltext results.push(...Search.performTermsSearch(searchTerms, excludedTerms)); normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); // let the scorer override scores with a custom scoring function if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item))); if (Scorer.score) { normalResults.forEach((item) => (item[4] = Scorer.score(item))); nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); } // now sort the results by score (in opposite order of appearance, since the // display function below uses pop() to retrieve items) and then // alphabetically results.sort((a, b) => { const leftScore = a[4]; const rightScore = b[4]; if (leftScore === rightScore) { // same score: sort alphabetically const leftTitle = a[1].toLowerCase(); const rightTitle = b[1].toLowerCase(); if (leftTitle === rightTitle) return 0; return leftTitle > rightTitle ? -1 : 1; // inverted is intentional } return leftScore > rightScore ? 1 : -1; }); // Sort each group of results by score and then alphabetically by name. normalResults.sort(_orderResultsByScoreThenName); nonMainIndexResults.sort(_orderResultsByScoreThenName); // Combine the result groups in (reverse) order. // Non-main index entries are typically arbitrary cross-references, // so display them after other results. let results = [...nonMainIndexResults, ...normalResults]; // remove duplicate search results // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept
-
@@ -362,7 +409,12 @@ }return acc; }, []); results = results.reverse(); return results.reverse(); }, query: (query) => { const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); // for debugging //Search.lastresults = results.slice(); // a copy
-
@@ -433,16 +485,14 @@ "#" + anchor,descr, score, filenames[match[0]], SearchResultKind.object, ]); }; Object.keys(objects).forEach((prefix) => { if (!(objects[prefix] instanceof Array)) { objects[prefix] = Object.entries(objects[prefix]).map(([name, match]) => [...match, name]); } Object.keys(objects).forEach((prefix) => objects[prefix].forEach((array) => objectSearchCallback(prefix, array) ); }); ) ); return results; },
-
@@ -470,14 +520,18 @@ ];// add support for partial matches if (word.length > 2) { const escapedWord = _escapeRegExp(word); Object.keys(terms).forEach((term) => { if (term.match(escapedWord) && !terms[word]) arr.push({ files: terms[term], score: Scorer.partialTerm }); }); Object.keys(titleTerms).forEach((term) => { if (term.match(escapedWord) && !titleTerms[word]) arr.push({ files: titleTerms[word], score: Scorer.partialTitle }); }); if (!terms.hasOwnProperty(word)) { Object.keys(terms).forEach((term) => { if (term.match(escapedWord)) arr.push({ files: terms[term], score: Scorer.partialTerm }); }); } if (!titleTerms.hasOwnProperty(word)) { Object.keys(titleTerms).forEach((term) => { if (term.match(escapedWord)) arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); }); } } // no match but word was a required one
-
@@ -500,9 +554,8 @@ });// create the mapping files.forEach((file) => { if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); else fileMap.set(file, [word]); if (!fileMap.has(file)) fileMap.set(file, [word]); else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); }); });
-
@@ -543,6 +596,7 @@ "",null, score, filenames[file], SearchResultKind.text, ]); } return results;
-
@@ -553,8 +607,8 @@ * helper function to return a node containing the* search summary for a given text. keywords is a list * of stemmed words. */ makeSearchSummary: (htmlText, keywords) => { const text = Search.htmlToText(htmlText); makeSearchSummary: (htmlText, keywords, anchor) => { const text = Search.htmlToText(htmlText, anchor); if (text === "") return null; const textLower = text.toLowerCase();
-
-
-
@@ -1,3 +1,5 @@<!DOCTYPE html> <html class="writer-html5" lang="en" data-content_root="./"> <head>
-
@@ -5,17 +7,16 @@ <meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Index — Mathematics in Lean 0.1 documentation</title> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=80d5e7a1" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=86f27845" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" /> <link rel="stylesheet" type="text/css" href="_static/css/custom.css?v=0731ccc3" /> <link rel="shortcut icon" href="_static/favicon.ico"/> <script src="_static/jquery.js?v=8dae8fb0"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=888ff710"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script src="_static/jquery.js?v=5d32c60e"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=9bcbadda"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script src="_static/js/theme.js"></script> <link rel="index" title="Index" href="#" /> <link rel="search" title="Search" href="search.html" />
-
-
-
@@ -1,3 +1,5 @@<!DOCTYPE html> <html class="writer-html5" lang="en" data-content_root="./"> <head>
-
@@ -6,17 +8,17 @@<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Mathematics in Lean — Mathematics in Lean 0.1 documentation</title> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=80d5e7a1" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=86f27845" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" /> <link rel="stylesheet" type="text/css" href="_static/css/custom.css?v=0731ccc3" /> <link rel="shortcut icon" href="_static/favicon.ico"/> <script src="_static/jquery.js?v=8dae8fb0"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=888ff710"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script src="_static/jquery.js?v=5d32c60e"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=9bcbadda"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script async="async" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> <script src="_static/js/theme.js"></script> <link rel="index" title="Index" href="genindex.html" /> <link rel="search" title="Search" href="search.html" />
-
-
-
@@ -1,3 +1,5 @@<!DOCTYPE html> <html class="writer-html5" lang="en" data-content_root="./"> <head>
-
@@ -5,18 +7,17 @@ <meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Search — Mathematics in Lean 0.1 documentation</title> <link rel="stylesheet" type="text/css" href="_static/pygments.css?v=80d5e7a1" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=86f27845" /> <link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=e59714d7" /> <link rel="stylesheet" type="text/css" href="_static/css/custom.css?v=0731ccc3" /> <link rel="shortcut icon" href="_static/favicon.ico"/> <script src="_static/jquery.js?v=8dae8fb0"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=888ff710"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script src="_static/jquery.js?v=5d32c60e"></script> <script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script> <script src="_static/documentation_options.js?v=2709fde1"></script> <script src="_static/doctools.js?v=9bcbadda"></script> <script src="_static/sphinx_highlight.js?v=dc90522c"></script> <script src="_static/js/theme.js"></script> <script src="_static/searchtools.js"></script> <script src="_static/language_data.js"></script>
-
-
-
@@ -1,1 +1,1 @@Search.setIndex({"docnames": ["C01_Introduction", "C02_Basics", "C03_Logic", "C04_Sets_and_Functions", "C05_Elementary_Number_Theory", "C06_Structures", "C07_Hierarchies", "C08_Groups_and_Rings", "C09_Linear_Algebra", "C10_Topology", "C11_Differential_Calculus", "C12_Integration_and_Measure_Theory", "genindex", "index"], "filenames": ["C01_Introduction.rst", "C02_Basics.rst", "C03_Logic.rst", "C04_Sets_and_Functions.rst", "C05_Elementary_Number_Theory.rst", "C06_Structures.rst", "C07_Hierarchies.rst", "C08_Groups_and_Rings.rst", "C09_Linear_Algebra.rst", "C10_Topology.rst", "C11_Differential_Calculus.rst", "C12_Integration_and_Measure_Theory.rst", "genindex.rst", "index.rst"], "titles": ["<span class=\"section-number\">1. </span>Introduction", "<span class=\"section-number\">2. </span>Basics", "<span class=\"section-number\">3. </span>Logic", "<span class=\"section-number\">4. </span>Sets and Functions", "<span class=\"section-number\">5. </span>Elementary Number Theory", "<span class=\"section-number\">6. </span>Structures", "<span class=\"section-number\">7. </span>Hierarchies", "<span class=\"section-number\">8. </span>Groups and Rings", "<span class=\"section-number\">9. </span>Linear algebra", "<span class=\"section-number\">10. </span>Topology", "<span class=\"section-number\">11. </span>Differential Calculus", "<span class=\"section-number\">12. </span>Integration and Measure Theory", "Index", "Mathematics in Lean"], "terms": {"The": [0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 13], "goal": [0, 1, 2, 3, 4, 5, 8, 9], "thi": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "book": [0, 2, 8, 9], "i": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "teach": 0, "you": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "formal": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "mathemat": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "us": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13], "lean": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "4": [0, 1, 2, 4, 5, 7, 8, 9, 10], "interact": [0, 5, 6, 7, 8, 11], "proof": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "assist": [0, 2, 5], "It": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "assum": [0, 1, 2, 3, 4, 6, 7, 8, 9], "know": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "some": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "doe": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "requir": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "much": [0, 2, 4, 6, 7, 8, 9, 10], "although": [0, 3, 4, 5, 6, 7, 8, 9], "we": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "cover": [0, 1, 3, 6, 7, 8, 9, 10], "exampl": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13], "rang": [0, 2, 3, 4, 7, 8, 9], "from": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "number": [0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 13], "theori": [0, 1, 2, 3, 6, 7, 8, 9, 10, 13], "measur": [0, 5, 9, 10, 13], "analysi": [0, 5, 8, 10], "focu": [0, 1, 7, 8, 9, 11], "elementari": [0, 3, 5, 7, 8, 9, 13], "aspect": [0, 5, 7], "those": [0, 1, 2, 3, 5, 6, 7, 8, 9, 10], "field": [0, 1, 5, 6, 7, 8, 10], "hope": [0, 1, 8], "thei": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "ar": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "familiar": [0, 1, 4, 5, 8, 9, 10], "can": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "pick": [0, 6], "them": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "up": [0, 2, 3, 4, 5, 6, 7, 9], "go": [0, 1, 2, 3, 4, 6, 8, 9], "also": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "don": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "t": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "presuppos": 0, "ani": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "background": [0, 7], "method": [0, 2, 3, 4, 5], "seen": [0, 1, 2, 4, 5, 6, 7, 8, 9], "kind": [0, 1, 6, 8, 9], "comput": [0, 2, 3, 4, 5, 7, 8, 10, 11], "program": [0, 1, 2], "write": [0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11], "definit": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "theorem": [0, 2, 4, 5, 7, 8, 9, 10, 11, 13], "regiment": 0, "languag": [0, 1, 2, 3], "like": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "understand": [0, 2, 3, 4, 5, 6, 7, 8, 9], "In": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "return": [0, 2, 3, 4, 5, 7, 8, 9], "provid": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "feedback": 0, "inform": [0, 1, 2, 3, 5, 6, 8, 9], "interpret": [0, 1, 4, 5, 7, 8, 9], "express": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "guarante": [0, 3, 5, 8], "well": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "form": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "ultim": 0, "certifi": 0, "correct": [0, 1, 7], "our": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "learn": [0, 1, 4, 5], "more": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 13], "about": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 13], "project": [0, 4, 5, 7, 8, 9], "page": [0, 1, 4], "commun": [0, 4], "web": [0, 1, 4], "tutori": 0, "base": [0, 2, 3, 4, 6, 7, 9, 10, 13], "": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "larg": [0, 6, 9], "ever": [0, 9], "grow": [0, 6, 7], "librari": [0, 1, 2, 3, 4, 5, 7, 9, 10], "mathlib": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "strongli": 0, "recommend": [0, 1, 3], "join": [0, 1, 5], "zulip": [0, 4], "onlin": 0, "chat": 0, "group": [0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 13], "haven": [0, 2, 6, 9], "alreadi": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "ll": [0, 2, 4, 6, 9], "find": [0, 1, 2, 4, 5, 6, 8, 9], "live": [0, 5, 8], "welcom": [0, 1], "enthusiast": 0, "happi": 0, "answer": [0, 5, 9], "question": [0, 4, 6, 9, 11], "offer": [0, 2, 5, 9], "moral": [0, 5, 7], "support": [0, 1, 2, 3, 4, 5, 6, 8, 9], "read": [0, 1, 4, 5, 6, 7, 8, 9], "pdf": 0, "html": 0, "version": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "design": [0, 1, 2, 3, 5, 7, 8, 9], "run": 0, "insid": [0, 1, 2, 3, 7], "v": [0, 1, 2, 3, 5, 8, 9], "code": [0, 1, 2, 3, 5, 6, 8], "editor": [0, 1], "To": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "instal": [0, 6], "follow": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "instruct": [0, 1, 2, 9], "make": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "sure": [0, 1, 2, 3, 5, 6, 7, 8], "have": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "git": 0, "fetch": 0, "mathematics_in_lean": 0, "repositori": [0, 1], "open": [0, 1, 2, 3, 4, 5, 7, 8, 10, 11], "each": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "section": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "ha": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "an": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "associ": [0, 1, 2, 4, 5, 6, 7, 8, 9, 11], "file": [0, 1, 4, 5, 6, 7, 9], "exercis": [0, 1, 2, 3, 5, 6, 7, 8, 9, 10], "folder": 0, "mil": 0, "organ": 0, "chapter": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "copi": [0, 3, 4, 6, 7, 8, 9], "experi": [0, 1, 9], "do": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "leav": [0, 1, 2, 3, 5, 6, 7], "origin": [0, 1, 5, 7], "intact": 0, "easier": [0, 1, 3, 4, 6, 9], "updat": 0, "chang": [0, 1, 2, 4, 5, 9, 11], "see": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "below": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "call": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "my_fil": 0, "whatev": [0, 2, 4], "want": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "creat": [0, 1, 4, 6], "your": [0, 1, 2, 3, 5, 6, 7, 9], "own": [0, 1, 4, 5, 6], "At": [0, 1, 2, 4, 5, 6, 8], "point": [0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11], "textbook": [0, 1, 2], "side": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "panel": 0, "type": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "ctrl": [0, 1, 2, 4, 5], "shift": [0, 1, 6, 9], "p": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "command": [0, 1, 2, 3, 4, 5, 6, 7, 8], "maco": 0, "doc": 0, "show": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "document": [0, 1, 3, 4, 6], "resourc": 0, "bar": [0, 1, 2, 8], "appear": [0, 1, 2, 5, 6, 7, 8, 9], "press": [0, 8], "select": [0, 9], "soon": [0, 2, 6, 7, 8, 9], "highlight": [0, 2], "menu": [0, 1], "window": [0, 1, 2, 5], "click": [0, 1, 3, 4, 5, 6], "altern": [0, 1, 2, 3, 4, 5, 6, 9], "cloud": 0, "gitpod": 0, "how": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "github": [0, 1], "still": [0, 1, 2, 3, 4, 5, 6, 8, 9, 11], "work": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "describ": [0, 1, 2, 3, 4, 5, 6, 8, 9], "abov": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "progress": [0, 1, 5, 7], "pull": [0, 7, 9], "lake": 0, "ex": [0, 2], "cach": 0, "content": [0, 1, 2, 4, 9], "which": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "why": [0, 2, 4, 6, 7, 8, 9], "suggest": [0, 2, 4, 5, 8, 9], "intend": [0, 1, 2, 5], "while": [0, 1, 2, 6, 7, 8, 9], "contain": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "explan": [0, 7, 8, 9], "hint": [0, 1, 2, 11], "text": [0, 3, 5, 9], "often": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "includ": [0, 1, 2, 3, 4, 6, 7, 8, 9, 10], "one": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "eval": [0, 7, 8], "hello": 0, "world": 0, "should": [0, 1, 2, 3, 4, 5, 6, 7, 9, 10], "abl": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10], "correspond": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "If": [0, 1, 2, 3, 4, 5, 6, 8, 9], "line": [0, 1, 2, 3, 4, 6, 7, 8], "hover": [0, 1, 2, 3, 4, 5], "cursor": [0, 1, 2], "over": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "respons": [0, 1], "pop": 0, "encourag": [0, 1, 2, 3, 4, 5], "edit": 0, "try": [0, 1, 2, 3, 4, 5, 6, 8, 9], "moreov": [0, 1, 4, 5, 9], "lot": [0, 1, 3, 5, 6, 7, 8, 9], "challeng": [0, 1, 2, 3, 5, 10], "rush": 0, "past": [0, 1, 7], "just": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "through": [0, 1, 3, 4, 5, 6, 7, 8, 9], "central": [0, 4], "all": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "when": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "feel": [0, 1, 2, 6, 8, 9], "comfort": 0, "master": [0, 1, 4], "relev": [0, 1, 2, 4, 5, 6, 7, 8, 9], "skill": [0, 1, 2, 3, 4], "free": [0, 1, 7, 8, 9], "move": [0, 1, 2, 6, 8, 9], "alwai": [0, 1, 2, 3, 5, 6, 7, 8], "compar": [0, 5, 6, 8, 9], "solut": [0, 1, 4, 6], "ones": [0, 1, 2, 3, 5, 8, 11], "put": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "simpli": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "tool": [0, 1, 5, 6], "build": [0, 2, 4, 6, 7, 8, 9, 13], "complex": [0, 1, 2, 4, 5, 7, 8, 10, 11], "known": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "depend": [0, 2, 3, 4, 5, 6, 7, 8, 9], "everi": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "check": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "print": [0, 3, 4, 5, 11], "\u2115": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "These": [0, 1, 3, 4, 5, 7, 10, 11], "object": [0, 1, 2, 3, 4, 5, 7, 8, 13], "2": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "def": [0, 2, 3, 4, 5, 6, 7, 8, 9], "f": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "x": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "3": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "prop": [0, 2, 3, 4, 5, 6, 7, 8, 9, 11], "statement": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "fermatlasttheorem": 0, "y": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "z": [0, 1, 2, 5, 6, 7, 8, 9, 10, 11], "n": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "0": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "where": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "itself": [0, 2, 3, 5, 6, 7, 8, 9, 10], "Such": [0, 1, 2, 6], "proposit": [0, 2, 3, 4, 5], "easi": [0, 4, 5, 6, 7, 8, 9], "rfl": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "hard": [0, 1, 3, 5, 6, 7], "sorri": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "manag": [0, 1, 4, 5, 9], "construct": [0, 2, 3, 4, 5, 6, 7, 8, 9], "accept": [0, 1, 2, 8, 9], "term": [0, 1, 2, 3, 4, 5, 7, 8, 9], "done": [0, 2, 3, 4, 6, 7, 8, 9], "someth": [0, 1, 2, 4, 6, 8, 9], "veri": [0, 2, 4, 6, 7, 8, 9, 11], "impress": 0, "cheat": [0, 1], "so": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "now": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "game": [0, 6], "left": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "rule": [0, 2, 4, 5, 6, 8, 9], "complementari": 0, "companion": [0, 1], "prove": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13], "thorough": 0, "underli": [0, 1, 5, 6, 7, 8], "logic": [0, 1, 3, 4, 5, 7, 8, 13], "framework": [0, 8], "core": [0, 4, 5], "syntax": [0, 1, 2, 4, 6, 8], "peopl": [0, 1], "who": [0, 9], "prefer": [0, 1, 2, 3], "user": [0, 6], "manual": [0, 3, 4], "befor": [0, 1, 2, 3, 4, 5, 6, 7, 8], "new": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "dishwash": 0, "person": 0, "hit": [0, 1], "button": 0, "figur": [0, 1, 2, 5], "out": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "activ": 0, "potscrubb": 0, "featur": [0, 2, 4, 7], "later": [0, 1, 2, 4, 5, 6, 7, 8, 9], "sens": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10], "here": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "refer": [0, 1, 2, 4, 5, 6, 8, 9, 10], "back": [0, 1, 2, 5, 6, 7, 8, 9], "necessari": [0, 2, 4, 5, 7, 8], "anoth": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "thing": [0, 1, 2, 3, 4, 5, 6, 8, 9], "distinguish": [0, 5, 6, 7, 9, 10], "place": [0, 1, 2, 5, 8, 9], "greater": [0, 1, 2, 3, 4, 9], "emphasi": [0, 6], "tactic": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "given": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "two": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "wai": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "down": [0, 3, 4, 6, 9], "themselv": [0, 4, 5], "suitabl": [0, 1, 2, 5, 9], "descript": [0, 1, 2, 4, 9], "thereof": 0, "For": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "repres": [0, 1, 2, 3, 4, 5, 6, 10], "fact": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13], "even": [0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11], "m": [0, 1, 2, 4, 6, 7, 8, 9, 10], "nat": [0, 1, 2, 3, 4, 5, 7, 9], "fun": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "k": [0, 2, 4, 5, 7, 8, 9, 10], "hk": [0, 10], "hmn": 0, "rw": [0, 2, 3, 4, 5, 6, 7, 8, 9, 13], "mul_add": [0, 1, 4, 6], "l": [0, 1, 8, 10, 11], "_": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "compress": [0, 1, 9], "singl": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10], "instead": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "style": [0, 1], "same": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "comment": [0, 4], "henc": [0, 2, 3, 4, 5, 6, 8, 9, 10], "ignor": [0, 5, 7, 8, 9], "sai": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "natur": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "rintro": [0, 2, 3, 4, 7, 8, 9], "need": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "twice": [0, 1, 9], "let": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "substitut": [0, 2], "obviou": [0, 4, 5, 6], "ring": [0, 1, 2, 3, 4, 5, 6, 8, 13], "As": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "enter": [0, 1, 2, 3, 7, 9], "displai": [0, 1, 2, 6], "state": [0, 1, 2, 3, 4, 6, 7, 8, 9, 10], "separ": [0, 1, 2, 4, 5, 8], "tell": [0, 2, 3, 4, 5, 6, 7, 8], "what": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "establish": [0, 1, 2, 3, 4, 5], "task": [0, 2, 4, 5, 6, 9], "remain": [0, 1, 2, 3, 5, 6, 9], "replai": 0, "step": [0, 1, 2, 3, 4, 5, 6], "sinc": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "continu": [0, 1, 4, 5, 6, 8, 11], "first": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "introduc": [0, 1, 2, 3, 4, 8, 9, 11], "could": [0, 1, 2, 4, 5, 6, 7, 8, 9], "renam": 0, "decompos": [0, 3], "hypothesi": [0, 1, 2, 3, 4], "assumpt": [0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11], "second": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "declar": [0, 1, 4, 5, 6, 7, 8], "next": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "rewrit": [0, 1, 2, 3, 4, 5, 6, 8, 9], "replac": [0, 1, 2, 3, 4, 6, 7, 8], "solv": [0, 1, 2, 3, 4, 5, 6, 8, 9], "result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "abil": 0, "small": [0, 2, 4, 5, 9], "increment": [0, 1], "extrem": [0, 6, 9], "power": [0, 1, 3, 4, 5, 6, 8], "reason": [0, 1, 2, 4, 5, 6, 7, 8, 9], "quicker": 0, "than": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "There": [0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11], "isn": [0, 2, 3, 4, 6], "sharp": 0, "distinct": [0, 2, 3, 4, 5, 8, 9], "between": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "insert": [0, 2, 4, 5, 7, 8, 9, 10], "did": [0, 2, 6, 9], "phrase": [0, 1, 2, 4, 5, 8], "convers": [0, 2, 4, 7, 8, 9], "short": [0, 1, 2, 3, 4, 5, 8], "middl": [0, 1, 2, 9], "That": [0, 4, 5, 6], "said": [0, 2, 4, 5], "reduc": [0, 2, 3, 4, 5], "liner": 0, "carri": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "But": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "substanti": 0, "autom": [0, 1, 5], "justifi": [0, 1, 2, 9], "longer": [0, 4, 5], "calcul": [0, 2, 4, 5, 13], "bigger": [0, 3, 10], "inferenti": 0, "invok": [0, 1, 9], "simplifi": [0, 2, 3, 4, 5, 9, 11], "specif": [0, 1, 3, 4, 5, 6], "pariti": 0, "automat": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "intro": [0, 1, 2, 3, 4, 5, 6, 7, 9], "simp": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10], "parity_simp": 0, "big": [0, 5, 7, 8, 9, 10], "differ": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "onli": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "its": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "built": [0, 2, 6, 7, 8], "wherea": [0, 1, 2, 3, 5, 7, 9], "top": [0, 6, 7, 8, 9, 10], "meant": [0, 2, 6, 8], "complet": [0, 1, 2, 3, 4, 6, 7, 10], "extens": [0, 1, 6, 9, 10], "rather": [0, 1, 2, 4, 5, 6, 7, 8, 9], "think": [0, 1, 2, 3, 4, 5, 6, 8, 9, 10], "basic": [0, 2, 4, 5, 8, 9, 11, 13], "entri": [0, 5, 7, 8], "brows": [0, 1, 4, 7], "frustrat": [0, 6], "curv": 0, "steep": 0, "newcom": 0, "avail": [0, 1, 2, 4, 5, 6, 7, 8], "round": [0, 1, 5], "clock": 0, "doubt": 0, "enough": [0, 1, 2, 3, 4, 6, 7, 8, 9], "too": [0, 1, 3, 5, 6, 7, 8, 9], "contribut": [0, 3], "develop": [0, 1, 4, 7, 11], "mission": 0, "choos": [0, 2, 3, 4, 5, 6, 7, 9], "dive": 0, "come": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "forewarn": 0, "fundament": [0, 4, 5, 6, 11], "life": [0, 2], "mai": [0, 1, 2, 3, 5, 6, 7, 8, 9, 10], "never": [0, 6], "acknowledg": 0, "grate": [0, 5], "gabriel": 0, "ebner": 0, "set": [0, 1, 2, 4, 5, 6, 7, 10, 11, 13], "infrastructur": 0, "kim": 0, "morrison": 0, "mario": 0, "carneiro": 0, "help": [0, 1, 2, 3, 4, 5, 6, 8, 9], "port": 0, "takeshi": 0, "ab": [0, 2, 5, 7], "julian": 0, "berman": 0, "alex": 0, "best": 0, "thoma": 0, "brown": 0, "bulwi": 0, "cha": 0, "hanson": 0, "char": 0, "bryan": 0, "gin": 0, "ge": [0, 2, 5], "chen": 0, "steven": 0, "clontz": 0, "mauricio": 0, "collari": 0, "johan": 0, "commelin": 0, "mark": [0, 1, 2, 6, 9], "czubin": 0, "alexandru": 0, "duca": 0, "pierpaolo": 0, "frasa": 0, "deni": 0, "gorbachev": 0, "winston": 0, "de": 0, "greef": 0, "mathieu": 0, "guai": 0, "paquet": 0, "marc": 0, "huisinga": 0, "benjamin": 0, "jone": 0, "k\u00fclshammer": 0, "victor": 0, "liu": 0, "jimmi": 0, "lu": 0, "martin": 0, "c": [0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11], "giovanni": 0, "mascellani": 0, "john": 0, "mcdowel": 0, "joseph": 0, "mckinsei": 0, "bhavik": 0, "mehta": 0, "isaiah": 0, "mindich": 0, "kabelo": 0, "moiloa": 0, "hunter": 0, "monro": 0, "pietro": 0, "monticon": 0, "oliv": 0, "nash": 0, "emanuel": 0, "natal": 0, "filippo": 0, "A": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "e": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "nuccio": 0, "pim": 0, "ott": 0, "bartosz": 0, "piotrowski": 0, "nicola": 0, "rolland": 0, "keith": 0, "yannick": 0, "seurin": 0, "guilherm": 0, "silva": 0, "bernardo": 0, "subercaseaux": 0, "pedro": 0, "s\u00e1nchez": 0, "terraf": 0, "matthew": 0, "toohei": 0, "alistair": 0, "tucker": 0, "flori": 0, "van": 0, "doorn": 0, "eric": 0, "wieser": 0, "other": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "been": [0, 1, 2, 4, 5, 6, 8, 10], "partial": [0, 1, 2, 3, 5, 6, 7, 8], "hoskinson": 0, "center": [0, 9], "nut": 1, "bolt": 1, "gener": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "without": [1, 2, 4, 5, 6, 7, 8, 9, 10], "u": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "net": 1, "hand": [1, 2, 3, 4, 5, 6, 8, 9], "equal": [1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "right": [1, 2, 3, 4, 5, 6, 8, 9, 10], "tantamount": [1, 3], "name": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "b": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "real": [1, 2, 3, 4, 5, 6, 8, 9, 10, 11], "mul_assoc": [1, 2, 4, 5, 6, 7], "mul_comm": [1, 2, 4, 5, 6, 7], "elimin": 1, "explicitli": [1, 2, 3, 5, 6, 7, 8, 9, 10], "purpos": [1, 2, 3, 4, 5, 6, 8, 9], "illustr": [1, 2, 3, 4, 5, 7], "multipl": [1, 2, 3, 4, 5, 6, 7, 8, 10], "written": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "howev": [1, 2, 5, 6, 7, 8, 9, 10], "good": [1, 2, 3, 4, 5, 6, 7, 8, 9], "mind": [1, 2, 5, 6, 7], "notat": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "convent": [1, 5, 7, 11], "parenthes": [1, 2, 3, 4], "\u211d": [1, 2, 3, 5, 6, 7, 8, 9, 10, 11], "import": [1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "begin": [1, 2, 3, 4, 5, 6], "sake": [1, 4], "breviti": [1, 5], "suppress": 1, "happen": [1, 6, 9], "charact": [1, 3, 6], "r": [1, 2, 4, 5, 6, 7, 8, 9], "symbol": [1, 2, 5, 6, 7], "doesn": [1, 2, 7, 8, 9], "until": [1, 4, 6, 9], "space": [1, 2, 3, 5, 6, 7, 11, 13], "tab": [1, 3, 4], "kei": [1, 4, 5, 7, 8, 9], "curiou": [1, 6], "abbrevi": [1, 2, 3, 5, 8], "get": [1, 2, 3, 4, 6, 7, 8, 9, 10, 13], "access": [1, 3, 5, 6, 7, 8, 9, 11], "keyboard": 1, "easili": [1, 4, 5, 6, 7, 8], "backslash": [1, 3], "lead": [1, 2, 4, 5, 6, 7, 8, 9], "lean4": 1, "input": [1, 3, 8, 9], "leader": 1, "report": 1, "current": [1, 2, 5, 6], "infoview": [1, 6], "typic": [1, 7], "might": [1, 2, 3, 4, 5, 7], "look": [1, 2, 3, 4, 6, 7, 8, 9], "1": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "h\u2081": [1, 2, 3, 4], "prime": [1, 2, 3, 5, 6, 7, 8, 13], "h\u2082": [1, 3, 4], "h\u2083": [1, 3], "denot": [1, 3, 4, 6, 7, 8, 9], "context": [1, 2, 4, 5, 6, 7, 8, 9, 10, 11], "plai": [1, 3, 4, 6, 7, 8, 9], "three": [1, 2, 4, 5, 7, 9], "label": [1, 2], "everyth": [1, 2, 6, 9], "identifi": [1, 2, 4, 8], "subscript": [1, 8], "h": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "legal": 1, "would": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "h1": [1, 2, 3, 4, 5], "h2": [1, 2, 3, 5], "h3": 1, "foo": [1, 5], "baz": 1, "last": [1, 2, 3, 4, 5, 6, 7, 9], "sometim": [1, 2, 3, 4, 5, 6, 7, 8, 9], "target": [1, 6, 7, 8, 9, 11], "combin": [1, 2, 5, 6, 7, 8, 9], "practic": [1, 2, 3, 6, 7, 9], "mean": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "usual": [1, 2, 3, 4, 5, 7, 8, 9, 11], "clear": [1, 2, 4, 5, 6], "case": [1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "With": [1, 3, 4, 6, 9], "arrow": [1, 2, 6, 9], "revers": [1, 2, 3, 5, 9], "note": [1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "noth": [1, 2, 3, 4, 5, 6, 7], "argument": [1, 2, 3, 4, 5, 6, 7, 8, 9], "tri": [1, 2, 4, 6], "match": [1, 2, 5], "pattern": [1, 2, 3, 5, 6], "local": [1, 2, 6, 9, 10], "d": [1, 2, 4, 5, 7, 8, 10], "sub_self": [1, 2], "hyp": 1, "list": [1, 2, 3, 4, 5, 8], "comma": [1, 8], "squar": [1, 2, 4, 5, 6, 7, 8], "bracket": [1, 2, 5, 6, 7], "after": [1, 2, 4, 6, 8, 9, 10], "trick": [1, 2, 4, 6, 10], "variabl": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "onc": [1, 2, 3, 4, 5, 6, 7, 9, 11], "outsid": [1, 4, 8], "inspect": 1, "reveal": [1, 8], "inde": [1, 5, 6, 7, 8, 9, 10], "delimit": 1, "scope": [1, 2, 3, 5, 7, 8], "end": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "block": [1, 4, 7], "final": [1, 2, 3, 5, 7, 8, 9, 11], "recal": [1, 2, 4, 5, 7, 9, 11], "introduct": [1, 2, 7, 9, 13], "determin": [1, 5, 7, 8, 9], "both": [1, 2, 3, 4, 5, 6, 7, 9, 10], "expect": [1, 2, 3, 4, 5, 6, 7, 8, 9], "rais": [1, 4], "error": [1, 2, 3, 6], "explain": [1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "output": [1, 7], "meanwhil": [1, 4], "take": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "two_mul": 1, "add_mul": [1, 6], "distribut": [1, 4, 5, 6], "addit": [1, 2, 4, 5, 6, 7, 8, 9, 10, 11], "add_assoc": [1, 4, 5, 6], "precis": [1, 3, 7, 8, 9, 10], "possibl": [1, 2, 3, 4, 5, 7, 9], "calc": [1, 2, 3, 5, 7, 9], "keyword": [1, 2, 4, 5], "notic": [1, 2, 3, 4, 5, 7, 9], "finicki": 1, "underscor": [1, 2, 3, 8], "justif": [1, 2], "format": 1, "indic": [1, 2, 3, 5, 6], "indent": 1, "One": [1, 2, 3, 4, 5, 6, 7, 8, 9], "outlin": [1, 2, 4, 9], "modulo": [1, 4, 5], "individu": 1, "pure": [1, 9], "littl": [1, 2, 9, 10], "underneath": [1, 3], "pow_two": [1, 4], "mul_sub": 1, "add_sub": 1, "sub_sub": 1, "add_zero": [1, 5, 6], "perform": [1, 2, 3], "exact": [1, 2, 3, 4, 5, 7, 8, 9], "becaus": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "exactli": [1, 2, 3, 5, 6, 7, 9], "close": [1, 2, 3, 6, 7, 8, 10, 11], "bit": [1, 2, 4, 6, 7, 8, 9], "commut": [1, 2, 3, 4, 5, 6, 7, 8, 10], "long": [1, 2, 3, 5, 6, 7, 8, 10], "axiom": [1, 2, 3, 5, 6, 7, 8, 9, 11], "indirectli": 1, "data": [1, 2, 4, 5, 6, 8, 9], "similar": [1, 2, 3, 5, 6, 7, 8, 9], "common": [1, 2, 3, 4, 5, 7, 8, 9], "variat": [1, 3, 4, 5, 9, 10], "nth_rw": 1, "allow": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "particular": [1, 2, 5, 6, 7, 8, 9], "instanc": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "enumer": [1, 2], "start": [1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 13], "occurr": 1, "consist": [1, 3, 5, 6, 7, 8, 9, 10], "collect": [1, 2, 3, 5, 8, 9, 11], "oper": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "time": [1, 4, 5, 6, 8, 9, 10, 11], "constant": [1, 2, 7, 11], "mapsto": [1, 5], "abelian": [1, 5, 6, 8], "negat": [1, 5, 13], "invers": [1, 3, 5, 6, 7, 8, 10, 11], "add_comm": [1, 4, 5, 6, 7], "zero_add": [1, 4, 5, 6], "neg_add_cancel": [1, 5], "mul_on": [1, 5, 6, 7], "one_mul": [1, 2, 5, 6], "being": [1, 3, 5, 7, 8, 9, 10], "suffic": [1, 2, 3, 7, 9], "give": [1, 2, 3, 4, 6, 7, 8, 9, 11], "element": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "concret": [1, 2, 4, 5, 6, 8, 9], "integ": [1, 2, 4, 6, 7, 13], "abstract": [1, 2, 5, 6, 7, 8, 9], "character": [1, 3, 4, 8, 9, 10], "axiomat": [1, 2, 3, 5], "train": [1, 6], "recogn": [1, 2, 4, 5, 6, 9], "appropri": [1, 2, 3, 5, 6], "\u2124": [1, 4, 5, 6, 7, 8], "ration": [1, 2, 4, 9], "\u211a": [1, 4, 7, 8, 9], "\u2102": [1, 5, 7, 8, 10], "extend": [1, 3, 4, 5, 6, 9, 11], "order": [1, 2, 3, 4, 5, 6, 8, 9, 10], "Not": [1, 5, 9], "properti": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "hold": [1, 2, 3, 4, 5, 7, 8, 9, 11], "arbitrari": [1, 2, 3, 4, 5, 7, 8], "taken": [1, 2], "cours": [1, 2, 4, 6, 7, 8, 9, 10, 11], "linear": [1, 2, 5, 7, 9, 13], "matric": [1, 5, 7, 13], "fail": [1, 2, 4, 5, 6, 8, 9, 11], "commr": [1, 2, 5, 7], "unchang": [1, 2], "linarith": [1, 2, 4, 5], "permiss": 1, "strike": [1, 2], "balanc": 1, "concis": [1, 5, 7], "readabl": [1, 2, 3, 8, 9], "strengthen": [1, 2, 4], "deriv": [1, 2, 4, 7, 10, 11], "most": [1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "organiz": 1, "mechan": [1, 2, 5], "namespac": [1, 2, 3, 4, 5, 7, 8, 9], "full": [1, 2, 3, 4, 5, 6, 7, 8, 9], "shorter": [1, 3, 4, 7, 9], "avoid": [1, 2, 3, 4, 5, 6, 7, 10], "due": [1, 6], "clash": 1, "myre": 1, "add_right_neg": 1, "effect": [1, 3, 6, 9], "temporarili": [1, 2], "reprov": [1, 7, 8], "care": [1, 2, 3, 5, 8], "earlier": [1, 7, 8], "pai": [1, 2, 6, 7, 9], "attent": [1, 2, 4, 6, 7, 9], "curli": [1, 2, 8], "implicit": [1, 2, 5, 6, 7, 8, 9, 10], "moment": [1, 2, 5], "worri": [1, 3, 4, 5, 7], "neg_add_cancel_left": 1, "add_neg_cancel_right": 1, "add_left_cancel": 1, "add_right_cancel": 1, "plan": [1, 6, 9], "brace": [1, 8], "imagin": 1, "situat": [1, 3, 6, 7, 9], "draw": [1, 5, 6], "conclus": [1, 2, 4], "hypothes": [1, 2, 3, 4, 5], "redund": [1, 5, 8, 9, 11], "few": [1, 2, 3, 4, 9], "extra": [1, 2, 3, 5, 6, 7, 9], "oner": 1, "complic": [1, 2, 6, 7, 8], "tediou": [1, 2, 6], "suppos": [1, 2, 3, 4, 5, 9], "infer": [1, 2, 3, 5, 6, 7, 8], "mul_zero": [1, 5, 6], "serv": [1, 3, 4, 5, 11], "therefor": [1, 4, 5, 8, 9], "promot": 1, "modular": 1, "subproof": 1, "wa": [1, 3, 7], "except": [1, 2, 5, 7], "ad": [1, 2, 3, 4, 5, 6, 8, 9], "variant": [1, 2, 7, 9], "whose": [1, 2, 4, 5, 6, 7, 8, 9, 10], "necessarili": [1, 8, 11], "miss": [1, 3, 4], "piec": [1, 4, 5, 6, 7, 9], "either": [1, 2, 3, 5, 6, 9], "becom": [1, 4, 5, 6, 9], "technic": [1, 5, 6, 8], "strictli": [1, 2, 10], "less": [1, 2, 3, 4, 5, 6, 7, 8, 9], "script": 1, "slightli": [1, 6, 7, 8, 9, 10], "clearer": [1, 3, 5], "human": 1, "reader": [1, 8, 9], "maintain": 1, "evolv": 1, "rememb": [1, 2, 3, 4, 5, 6, 7, 8, 9], "zero_mul": [1, 4, 5, 6], "By": [1, 3, 5, 6, 7, 8], "neg_eq_of_add_eq_zero": 1, "eq_neg_of_add_eq_zero": 1, "neg_zero": 1, "neg_neg": 1, "had": [1, 6, 8], "annot": [1, 2, 3, 4, 5, 6], "third": [1, 2, 3, 5, 9], "specifi": [1, 2, 3, 4, 5, 8, 9, 10, 11], "imposs": 1, "default": [1, 2, 3, 4, 5, 6, 7, 10], "subtract": [1, 4, 5], "provabl": [1, 3, 6, 9], "sub_eq_add_neg": 1, "On": [1, 2, 3, 5, 6, 8, 9, 11], "defin": [1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 13], "reflex": [1, 2, 5], "present": [1, 2, 4, 7, 9], "forc": [1, 2, 3, 7, 8], "unfold": [1, 2, 3, 4, 5, 9], "deal": [1, 2, 3, 4, 5, 8, 9], "equat": [1, 2, 3, 4, 5], "interchang": 1, "self_sub": 1, "effort": [1, 4], "one_add_one_eq_two": 1, "norm_num": [1, 2, 4, 5, 8], "strength": 1, "weaker": [1, 2], "notion": [1, 2, 3, 4, 5, 7, 8, 9, 10, 11], "addgroup": [1, 5, 7], "otherwis": [1, 2, 3, 4, 5, 7], "addcommgroup": [1, 7, 8], "commgroup": 1, "g": [1, 2, 3, 5, 6, 7, 8, 9, 10, 11], "inv_mul_cancel": [1, 5], "\u00b9": [1, 3, 5, 6, 7, 8, 9], "cocki": 1, "helper": 1, "along": [1, 4, 7, 9], "mul_inv_cancel": [1, 5, 7], "mul_inv_rev": 1, "non": [1, 3, 6, 7, 8, 9, 11], "abel": [1, 7], "noncomm_r": 1, "seem": [1, 2, 4, 6, 9, 10], "odd": [1, 2, 3, 4, 8], "partli": [1, 6, 7], "histor": [1, 7], "conveni": [1, 2, 3, 5, 6, 7, 8, 9], "great": [1, 5], "sort": [1, 3, 4], "inequ": [1, 2, 6, 9], "le": [1, 5, 6], "whenev": [1, 2, 4, 5, 8], "consid": [1, 2, 3, 4, 5, 6, 7, 9, 10, 11], "le_refl": [1, 2], "le_tran": [1, 2], "detail": [1, 2, 3, 4, 5, 6, 7], "unless": [1, 2, 5], "realli": [1, 2, 3, 4, 6, 7, 8, 9], "insist": [1, 6], "discuss": [1, 2, 4, 5, 6, 7, 8, 9, 10], "implic": [1, 8, 9, 13], "h\u2080": [1, 2, 3, 4, 9], "dot": [1, 7, 8, 9], "option": [1, 2, 4, 5, 6, 9], "within": [1, 2, 9], "visibl": 1, "must": [1, 5, 6, 8, 9], "decreas": [1, 5], "mode": [1, 2, 5], "entir": [1, 3, 5, 9, 10], "lt_of_le_of_lt": [1, 2], "lt_of_lt_of_l": 1, "lt_tran": [1, 2], "togeth": [1, 2, 3, 4, 5, 7, 9], "handl": [1, 3, 4, 6, 7], "arithmet": 1, "5": [1, 2, 5, 7, 8, 9, 10], "pass": [1, 5], "exp_le_exp": 1, "mpr": [1, 2, 5, 9], "exp": [1, 3], "applic": [1, 2, 5, 7, 11], "function": [1, 2, 4, 5, 6, 7, 8, 10, 11, 13], "compound": [1, 2, 9], "pars": [1, 3, 7], "exp_lt_exp": 1, "log_le_log": 1, "log": [1, 3, 11], "log_lt_log": 1, "add_le_add": [1, 2], "add_le_add_left": 1, "add_le_add_right": 1, "add_lt_add_of_le_of_lt": 1, "add_lt_add_of_lt_of_l": 1, "add_lt_add_left": 1, "add_lt_add_right": 1, "add_nonneg": [1, 5], "add_po": 1, "add_pos_of_pos_of_nonneg": 1, "exp_po": [1, 3], "bi": [1, 2, 5], "lr": 1, "iff": [1, 3, 7, 8, 9, 10, 11, 13], "connect": [1, 3, 5, 8, 9], "equival": [1, 2, 3, 4, 5, 7, 8, 9, 10, 11], "mp": [1, 2, 3, 4, 9], "forward": [1, 2, 5, 7, 9], "direct": [1, 2, 3, 6, 7, 9, 10], "stand": [1, 2, 4, 5, 6, 7, 8, 9, 10], "modu": 1, "ponen": 1, "respect": [1, 2, 3, 4, 5, 7, 8, 9], "thu": [1, 3, 4, 5, 9], "again": [1, 2, 3, 4, 5, 6, 7, 8, 9], "numer": [1, 4, 5], "constitut": 1, "part": [1, 2, 3, 4, 5, 6, 8, 9, 11], "strategi": [1, 2, 4], "api": 1, "reli": [1, 2, 5, 9], "guess": [1, 2, 3, 4, 5, 8], "cmd": [1, 2], "mac": [1, 2], "a_of_b_of_c": 1, "approxim": 1, "loud": 1, "probabl": [1, 5, 6, 9], "add_l": 1, "choic": [1, 2, 3, 5, 8, 9], "exist": [1, 2, 3, 6, 7, 8, 9], "jump": [1, 4, 5, 9], "nearbi": [1, 4], "sq_nonneg": 1, "delet": [1, 2, 3], "uncom": 1, "previou": [1, 2, 3, 5, 6, 7, 9, 10, 11], "confirm": [1, 2, 3, 4], "finish": [1, 2, 3, 4, 7], "job": 1, "pow_two_nonneg": [1, 2], "tend": [1, 9], "around": [1, 3, 6, 7, 8, 9, 11], "binari": [1, 2, 4, 5, 6, 8], "increas": 1, "worth": [1, 2, 5], "definition": [1, 4, 5, 6, 9], "principl": [1, 2, 3, 4, 6, 8, 10], "favor": [1, 5], "timesav": 1, "clever": 1, "involv": [1, 2, 4, 5, 6, 7, 8, 9], "nice": [1, 2, 4, 6, 7, 8, 9], "idea": [1, 2, 3, 5, 6, 8, 9], "abs_l": [1, 5], "constructor": [1, 2, 3, 4, 5, 6], "split": [1, 2, 3, 4], "conjunct": [1, 6, 13], "congratul": [1, 2, 4], "min": [1, 2, 9, 11], "uniqu": [1, 2, 3, 4, 5, 7, 8, 9], "min_le_left": 1, "min_le_right": 1, "le_min": 1, "max": [1, 2, 6, 8, 9, 11], "pair": [1, 2, 4, 5, 7, 9], "act": [1, 7, 8], "curri": 1, "logician": 1, "haskel": 1, "bind": [1, 3], "tighter": [1, 3], "infix": [1, 6], "le_antisymm": [1, 2], "usag": 1, "inconsist": [1, 8], "outer": 1, "level": [1, 2, 6, 8], "nest": [1, 2], "bother": [1, 3], "repetit": [1, 6], "foreshadow": 1, "univers": [1, 3, 5, 7, 8, 9, 13], "quantifi": [1, 3, 4, 5, 7, 9, 13], "desir": [1, 3, 6, 7, 9], "implicitli": [1, 2], "repeat": [1, 4, 5, 6], "mani": [1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 13], "shorten": [1, 2, 7], "Of": [1, 2, 4, 6, 7, 8, 9, 10, 11], "interest": [1, 2, 3, 5, 6, 8, 9], "vice": [1, 3], "versa": [1, 3], "word": [1, 2, 3, 4, 5, 7, 8, 9], "switch": [1, 6], "transit": [1, 2, 5, 9], "total": 1, "satisfi": [1, 3, 4, 5, 6, 9, 10], "disjunct": [1, 3, 13], "stick": [1, 2, 9, 10], "aux": [1, 2, 4, 9], "valu": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "yield": [1, 2, 3, 4, 5, 9], "made": [1, 2, 3, 5, 8, 9], "manifest": [1, 9], "triangl": [1, 2, 5], "abs_add": [1, 2], "add_sub_cancel_right": 1, "sub_add_cancel": 1, "relat": [1, 2, 3, 5, 6, 7, 8, 9, 10, 11], "divis": [1, 2, 4, 5, 6, 8], "Be": [1, 3], "ordinari": [1, 2, 4, 5, 7, 8, 9], "unicod": [1, 3, 6], "obtain": [1, 2, 4, 5, 9, 10], "dvd": 1, "dvd_tran": 1, "dvd_mul_of_dvd_left": 1, "dvd_mul_left": 1, "expon": 1, "expand": [1, 2, 3, 4, 5, 6, 8], "w": [1, 6, 8], "greatest": [1, 5, 9], "divisor": [1, 2, 4, 5, 7], "gcd": [1, 2, 4], "least": [1, 5, 6, 8, 9], "lcm": 1, "analog": [1, 2, 3, 4, 8, 9], "divid": [1, 2, 4, 5, 7], "gcd_zero_right": 1, "gcd_zero_left": 1, "lcm_zero_right": 1, "lcm_zero_left": 1, "dvd_antisymm": 1, "complain": 1, "ambigu": [1, 5], "_root_": [1, 3, 4], "saw": [1, 5, 6, 7, 8, 9], "govern": [1, 5], "class": [1, 4, 5, 6, 7, 8, 9, 10, 11], "antisymmetr": [1, 2], "\u03b1": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "partialord": [1, 2], "adopt": 1, "letter": [1, 5, 10], "\u03b2": [1, 2, 3, 5, 6, 8, 9, 11], "\u03b3": [1, 2, 5, 9], "carrier": [1, 5, 6, 7, 8], "greek": [1, 4], "especi": [1, 2, 5, 6, 7, 8, 9], "strict": [1, 2], "somewhat": [1, 3, 9], "lt_irrefl": [1, 2], "lt_iff_le_and_n": 1, "lattic": [1, 5, 6, 7, 9], "inf_le_left": [1, 9], "inf_le_right": 1, "le_inf": 1, "le_sup_left": 1, "le_sup_right": 1, "sup_l": 1, "lower": [1, 2, 4], "bound": [1, 2, 3, 4, 5, 8, 9, 10, 11], "upper": [1, 2], "glb": 1, "lub": 1, "infimum": [1, 6, 7, 8, 9, 11], "supremum": [1, 4, 6, 7, 8], "inf": [1, 6, 9], "sup": [1, 4, 9], "further": [1, 9], "matter": [1, 2], "meet": [1, 2, 3, 5], "keep": [1, 3, 5, 6, 7], "dictionari": 1, "subset": [1, 2, 3, 5, 9, 10], "domain": [1, 2, 3, 4, 5, 7, 9], "boolean": 1, "truth": [1, 4], "fals": [1, 2, 3, 4, 6], "true": [1, 2, 3, 6, 8, 9], "posit": [1, 3, 4, 5, 9, 11], "subspac": [1, 6, 13], "vector": [1, 3, 6, 7, 10, 13], "intersect": [1, 3, 5, 6, 7, 8, 9, 11], "sum": [1, 2, 4, 5, 6, 7, 9], "inclus": [1, 3, 7, 8, 9], "topologi": [1, 5, 6, 10, 13], "union": [1, 3, 4, 5, 6, 7, 8, 10, 11], "intermedi": [1, 6, 8, 9], "produc": [1, 2, 7, 10], "auto": [1, 6], "mysteri": [1, 5, 6], "unapp": 1, "tran": [1, 2, 4, 5, 6, 7, 8], "issu": [1, 4, 5, 6, 8, 9], "directli": [1, 2, 4, 5, 6, 8, 9], "inf_comm": [1, 7], "inf_assoc": 1, "sup_comm": 1, "sup_assoc": 1, "absorpt": 1, "law": [1, 7], "absorb1": 1, "absorb2": 1, "found": [1, 5, 7, 8, 10], "inf_sup_self": 1, "sup_inf_self": 1, "distriblattic": 1, "inf_sup_left": 1, "inf_sup_right": 1, "sup_inf_left": 1, "sup_inf_right": 1, "shown": [1, 5, 10, 11], "explicit": [1, 2, 5, 6, 8, 9], "nondistribut": 1, "finit": [1, 3, 4, 5, 7, 8, 9, 10, 11], "impli": [1, 2, 3, 4, 5, 8, 9], "larger": [1, 9], "compat": [1, 7, 9], "strictorderedr": 1, "mul_po": [1, 4], "mul_nonneg": 1, "coupl": [1, 2, 6, 8, 9], "bewar": [1, 6, 8], "metric": [1, 5, 10, 13], "equip": [1, 3, 5, 6, 7, 9, 10, 11], "distanc": [1, 2, 9, 10], "dist": [1, 9], "map": [1, 2, 3, 5, 6, 7, 9, 13], "metricspac": [1, 9, 10], "dist_self": 1, "dist_comm": [1, 9], "dist_triangl": [1, 9], "nonneg": [1, 5], "nonneg_of_mul_nonneg_left": 1, "dist_nonneg": [1, 9], "dealt": 2, "simpl": [2, 4, 5, 6, 10], "absolut": 2, "\u03b5": [2, 9, 10], "though": [2, 3, 4, 5], "treat": [2, 3, 5, 6, 7, 9, 10], "appli": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13], "my_lemma": 2, "\u03b4": [2, 9], "hb": [2, 9], "subsequ": [2, 4, 9], "lemma": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13], "mention": [2, 3, 5, 6, 7, 9], "my_lemma2": 2, "stage": [2, 5, 6], "my_lemma3": 2, "epo": 2, "ele1": 2, "xlt": 2, "ylt": 2, "essenti": [2, 3, 5, 7, 9], "colon": [2, 8], "off": [2, 3, 4], "my_lemma4": 2, "abs_mul": 2, "mul_le_mul": 2, "abs_nonneg": 2, "mul_lt_mul_right": 2, "extract": [2, 9], "hidden": 2, "expos": [2, 9], "predic": [2, 3, 4, 6, 7, 8, 9, 10], "fnub": 2, "fnlb": 2, "lambda": [2, 5], "hfa": 2, "hgb": 2, "dsimp": [2, 3, 5, 7, 8], "simplif": [2, 3, 4], "contract": 2, "anyhow": 2, "control": 2, "transform": [2, 3], "rest": [2, 3, 5, 7, 9], "routin": 2, "nnf": 2, "nng": 2, "nna": 2, "codomain": [2, 4, 9], "structur": [2, 4, 6, 7, 9, 10, 11, 13], "monoid": [2, 3, 4, 6, 8, 13], "fnub_add": 2, "orderedcanceladdcommmonoid": 2, "high": [2, 7], "monoton": [2, 6, 9], "nondecreas": [2, 4], "placehold": 2, "Or": [2, 3, 8], "backward": [2, 9], "subgoal": 2, "mf": 2, "mg": 2, "aleb": 2, "flag": [2, 3], "squiggli": 2, "marker": 2, "nnc": 2, "bbb": [2, 5], "fneven": 2, "fnodd": 2, "ef": 2, "eg": 2, "og": 2, "rid": 2, "won": [2, 4, 6, 7, 9], "cannot": [2, 3, 4, 5, 6, 7, 8, 9], "contrari": 2, "syntact": 2, "reduct": [2, 3, 5], "erw": 2, "harder": [2, 5, 8], "spot": 2, "manipul": [2, 5, 7, 8, 9], "foundat": [2, 3, 4, 5, 7, 8], "mundan": 2, "assert": [2, 3, 6, 7], "contrast": [2, 3, 5, 6, 9], "zermelo": 2, "fraenkel": 2, "sin": [2, 10], "co": [2, 7], "zf": 2, "defect": [2, 6, 9], "theoret": [2, 3, 8, 9], "motiv": [2, 8], "detect": 2, "meaningless": 2, "independ": [2, 3, 5, 8], "continuum": 2, "meta": [2, 6], "beyond": [2, 6, 10], "ask": [2, 4, 5, 6, 7, 9], "refl": [2, 3, 5, 6, 7, 8], "setub": 2, "inject": [2, 3, 4, 6, 7, 8, 9], "x_1": [2, 3], "x_2": [2, 3], "x\u2081": [2, 3, 5, 9], "x\u2082": [2, 3, 5], "add": [2, 4, 5, 6, 7, 8, 9, 10], "nonzero": [2, 4, 5, 11], "sourc": [2, 9], "inspir": 2, "add_left_inj": 2, "composit": [2, 3, 5, 6, 7, 8, 9], "injg": 2, "injf": [2, 3], "canon": [2, 3, 4, 5, 8], "exhibit": [2, 9], "anonym": [2, 3, 4, 5, 7], "angl": 2, "certain": [2, 6, 9], "fnhasub": 2, "fnhaslb": 2, "ubf": 2, "ubg": 2, "rcase": [2, 3, 4, 9], "ubfa": 2, "ubgb": 2, "unpack": [2, 3], "main": [2, 6, 8, 9, 10], "els": [2, 3, 4, 8], "turn": [2, 3, 4, 5, 6, 8, 9, 10], "fn_ub_add": 2, "lbf": 2, "lbg": 2, "recurs": [2, 3, 5, 13], "arbitrarili": [2, 9], "assign": [2, 3, 5, 6, 7], "compon": [2, 3, 5, 8, 9, 11], "destruct": 2, "tag": [2, 3, 6], "chosen": [2, 5], "intern": [2, 5, 7], "primit": [2, 3], "scientist": 2, "sight": [2, 6], "hurt": 2, "chanc": 2, "yourself": [2, 5], "compani": 2, "old": [2, 5, 6, 8], "chestnut": 2, "product": [2, 4, 5, 6, 7, 9, 11], "magic": [2, 5, 6], "verifi": 2, "sumofsquar": 2, "sumofsquares_mul": 2, "sosx": 2, "sosi": 2, "xeq": [2, 3], "yeq": 2, "insight": 2, "gaussian": [2, 7, 13], "sqrt": [2, 3, 4, 5], "norm": [2, 5, 9, 13], "reflect": 2, "di": [2, 5], "xy": [2, 5], "cryptic": 2, "easiest": [2, 4], "perspicu": 2, "6": [2, 4, 5, 6, 7, 8, 9, 10], "divab": 2, "divbc": 2, "beq": 2, "ceq": 2, "And": [2, 4, 6, 9], "pretti": [2, 6, 7, 8, 9], "Then": [2, 3, 5, 6, 7, 8, 9, 11], "divac": 2, "alpha": [2, 3], "beta": [2, 3], "surject": [2, 3, 7, 8, 9], "mul_div_cancel\u2080": 2, "field_simp": [2, 5], "denomin": [2, 4, 5], "hx": [2, 3, 5, 6, 7, 8, 10], "surjg": 2, "surjf": [2, 3], "contradict": [2, 3, 4], "speak": [2, 5, 7, 9], "irreflex": 2, "asymmetri": 2, "lt_asymm": 2, "eventu": [2, 3, 9], "fnuba": 2, "not_le_of_gt": 2, "not_lt_of_g": [2, 4, 5], "lt_of_not_g": 2, "le_of_not_gt": 2, "snippet": [2, 4, 5, 7, 8], "counterexampl": [2, 10], "monof": 2, "four": [2, 5], "valid": 2, "far": [2, 3, 6, 8, 9], "q": [2, 4, 5, 6, 7, 8, 9], "fourth": 2, "straightforward": [2, 6], "difficult": [2, 6], "conclud": [2, 10], "nonexist": 2, "contradictori": 2, "classic": [2, 3, 4, 7, 8], "by_contra": [2, 4], "not_not": 2, "front": 2, "push": [2, 4, 7, 9], "inward": 2, "facilit": [2, 8, 9], "push_neg": [2, 3, 4], "restat": [2, 6, 7, 8], "contrapos": [2, 3, 4], "similarli": [2, 3, 4, 5, 7, 8], "yet": [2, 3, 4, 5, 6, 8, 9], "semicolon": [2, 4], "falso": 2, "anyth": [2, 5, 9], "elim": 2, "strang": [2, 4, 7, 8], "fairli": 2, "reach": [2, 6], "37": 2, "exfalso": 2, "absurd": [2, 4], "slick": 2, "drop": 2, "manner": [2, 5], "analogi": [2, 5, 9, 10], "techniqu": [2, 9], "variou": [2, 3, 5, 6, 8, 11], "xltz": 2, "zlty": 2, "10": [2, 8, 9], "7": [2, 4, 5, 7, 8], "behav": [2, 3, 6, 8, 9], "roughli": [2, 3, 4], "friend": [2, 5], "were": [2, 4, 5, 8, 9], "inscrut": [2, 3], "gadget": [2, 9], "auxiliari": [2, 9], "pow_eq_zero": [2, 4], "doubl": [2, 3], "symmetr": [2, 3, 7], "abs_lt": 2, "dvd_gcd_iff": 2, "8": [2, 4, 7, 8, 9], "15": 2, "not_monotone_iff": 2, "aris": 2, "preorder": [2, 6, 9], "pre": [2, 8], "lt_iff_le_not_l": 2, "repeatedli": [2, 9], "instanti": [2, 5, 6, 9], "inl": [2, 3, 8], "inr": [2, 3, 8], "branch": [2, 3, 6], "le_or_gt": 2, "abs_of_nonneg": [2, 5], "abs_of_neg": 2, "against": 2, "immedi": [2, 3, 5, 6, 8], "attract": 2, "closer": [2, 9], "advantag": [2, 3, 4, 5, 7, 10], "myab": 2, "le_abs_self": 2, "neg_le_abs_self": 2, "enjoi": [2, 3, 4, 9], "pun": 2, "lt_ab": 2, "genuin": 2, "vertic": [2, 5, 8], "lt_trichotomi": 2, "xgt": 2, "dvd_mul_right": [2, 4], "eq_zero_or_eq_zero_of_mul_eq_zero": 2, "zero": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "nontrivi": [2, 3, 4, 5, 8, 9, 10], "integr": [2, 10, 13], "isdomain": [2, 7], "whether": [2, 3, 4, 6, 9], "em": [2, 3], "exclud": [2, 4], "by_cas": [2, 3, 4], "dispos": 2, "s_0": [2, 3], "s_1": 2, "s_2": 2, "ldot": [2, 3, 4], "varepsilon": [2, 9], "s_n": [2, 3], "render": [2, 4], "convergesto": 2, "ext": [2, 3, 4, 5, 6, 7, 8], "enabl": [2, 3, 4, 5], "actual": [2, 3, 4, 6, 7, 8, 9], "congr": 2, "reconcil": 2, "peel": 2, "convert": [2, 4, 7, 8], "quit": [2, 6, 9], "zero_lt_on": [2, 4], "fill": [2, 3, 4, 5], "convergesto_const": 2, "\u03b5po": [2, 9], "nge": 2, "abs_zero": 2, "save": 2, "troubl": [2, 3, 5], "pen": [2, 7], "paper": [2, 3, 5, 7, 8, 9, 11], "nt": 2, "maximum": [2, 4, 9], "implement": [2, 5, 6, 7, 8, 10], "convergesto_add": 2, "ct": 2, "clean": [2, 9], "\u03b52po": 2, "ht": 2, "le_of_max_le_left": 2, "le_of_max_le_right": 2, "tricki": [2, 3, 4, 6, 7], "convergesto_mul_const": 2, "acpo": 2, "abs_po": 2, "exists_abs_le_of_convergesto": 2, "strong": [2, 4], "n\u2080": 2, "bpo": [2, 9], "pos\u2080": 2, "div_po": 2, "n\u2081": 2, "convergesto_mul": 2, "sketch": [2, 3, 4, 9], "limit": [2, 6, 9], "bold": 2, "scratch": 2, "convergesto_uniqu": 2, "sa": 2, "sb": 2, "abn": 2, "na": 2, "hna": 2, "nb": 2, "hnb": 2, "absa": 2, "absb": 2, "observ": [2, 4, 9], "everywher": [2, 3, 6, 8, 9, 11], "linearord": 2, "vastli": 2, "awai": [2, 5], "vocabulari": [3, 8], "uniform": [3, 9, 10], "conceptu": [3, 7], "overload": 3, "verbos": 3, "system": [3, 4, 5, 6, 8], "wrong": 3, "ss": 3, "sub": [3, 9, 11, 13], "cap": 3, "un": 3, "cup": 3, "univ": [3, 9, 10, 11], "empti": [3, 4, 5, 7, 9, 11], "member": [3, 9], "membership": [3, 4, 6, 7, 8], "mem": [3, 8], "notin": 3, "ident": [3, 4, 5, 6, 7, 8, 9, 13], "databas": [3, 4, 6, 9], "unlik": [3, 4], "existenti": [3, 7, 13], "subset_def": 3, "inter_def": 3, "mem_setof": 3, "xu": 3, "mem_inter_iff": 3, "xsu": 3, "phenomenon": 3, "union_def": 3, "mem_union": [3, 4], "xtu": 3, "xt": 3, "unnecessari": [3, 7], "correctli": 3, "special": [3, 4, 5, 6, 7, 8, 9, 11], "rewritten": 3, "diff_eq": 3, "mem_diff": 3, "xstu": 3, "xnt": 3, "xnu": 3, "extension": [3, 5], "unsurprisingli": 3, "harm": 3, "and_comm": 3, "antisymm": 3, "hood": [3, 5, 8], "builder": 3, "not_even_iff_odd": 3, "not_even_iff": 3, "trivial": [3, 4, 7, 8, 9], "eq_two_or_odd": 3, "odd_iff": 3, "confus": [3, 4, 6, 7, 9], "fortun": 3, "agre": 3, "prime_iff": 3, "symm": [3, 4, 5, 6, 7, 8, 9, 10], "rwa": [3, 4, 5], "restrict": [3, 4, 7, 9], "signific": 3, "ball": [3, 10], "bex": 3, "bex_def": 3, "prime_x": 3, "slight": 3, "ssubt": 3, "index": [3, 6, 7, 8, 9], "model": [3, 8, 9], "sequenc": [3, 6, 9, 10, 13], "a_0": 3, "a_1": 3, "a_2": 3, "mem_iunion": 3, "xai": 3, "mem_iint": 3, "mem_iunion\u2082": 3, "mem_iinter\u2082": 3, "exists_prime_and_dvd": 3, "eq_univ": 3, "eq_univ_of_foral": 3, "exists_infinite_prim": 3, "\u2080": [3, 8], "sunion": 3, "sinter": 3, "relationship": [3, 4], "sunion_eq_biunion": 3, "sinter_eq_biint": 3, "preimag": [3, 7, 8, 9], "imag": [3, 4, 6, 7, 8, 9], "tripl": 3, "mem_image_of_mem": 3, "galoi": [3, 5, 8, 9], "image_subset_iff": 3, "represent": [3, 4, 5, 8], "asid": 3, "raini": 3, "dai": 3, "behavior": [3, 6, 9], "nonempti": [3, 7, 9], "condit": [3, 4, 6, 7, 8, 9, 10], "injon": [3, 11], "theme": 3, "rel": [3, 5, 8], "relativ": 3, "xpo": 3, "ypo": 3, "exp_log": 3, "ingredi": [3, 5, 9, 10], "inhabit": [3, 5, 9], "appeal": [3, 6], "choose_spec": 3, "noncomput": [3, 5, 7, 8], "inverse_spec": 3, "dif_po": 3, "dif_neg": 3, "if_po": 3, "if_neg": 3, "fulli": [3, 7, 8, 9], "alon": 3, "leftinvers": 3, "rightinvers": 3, "hack": 3, "half": [3, 7], "dozen": 3, "condens": 3, "cantor": 3, "famou": [3, 7], "j": [3, 7, 8], "intuit": [3, 9], "cardin": [3, 7, 8], "biject": [3, 5, 7, 8], "nineteenth": 3, "centuri": 3, "infinit": [3, 8, 9, 13], "dedekind": 3, "quickli": [3, 7, 11], "behind": [3, 7], "problem": [3, 4, 5, 6, 9], "shade": 3, "region": 3, "diagram": 3, "circ": [3, 5], "scale": 3, "inner": 3, "smaller": [3, 4, 9], "concentr": 3, "unshad": 3, "compos": [3, 5, 7, 9], "disjoint": [3, 7, 11], "sound": [3, 5, 6], "plausibl": 3, "delic": 3, "improv": [3, 4], "confid": 3, "better": [3, 4, 5, 6, 9], "invfun": [3, 5, 8], "leftinverse_invfun": 3, "invfun_eq": 3, "sbaux": 3, "sbset": 3, "s_": 3, "bigcup_": 3, "mathbb": [3, 4, 5, 7], "sbfun": 3, "complement": [3, 8, 9, 11], "outermost": 3, "setminu": 3, "sb_right_inv": 3, "goe": [3, 4, 5, 6, 9], "neither": [3, 5, 6, 8], "nor": [3, 5, 8], "sb_inject": 3, "hf": [3, 7, 9, 10, 11], "a_def": 3, "h_def": 3, "hxeq": 3, "xa": 3, "wlog": 3, "x\u2081a": 3, "resolve_left": 3, "x\u2082a": 3, "not_imp_self": 3, "x\u2082na": 3, "x\u2082eq": 3, "hn": [3, 4, 9, 10], "sb_fun": 3, "bring": [3, 4, 9], "tradeoff": 3, "encapsul": [3, 5, 10], "symmetri": [3, 6], "dwell": 3, "sb_surject": 3, "hg": [3, 9, 10, 11], "gya": 3, "xmem": 3, "sweet": 3, "schroeder_bernstein": 3, "substant": 4, "ancient": 4, "fraction": 4, "lowest": 4, "2c": 4, "4c": 4, "factor": [4, 5, 7, 8], "coprim": [4, 7], "smart": 4, "12": [4, 8], "encount": [4, 6], "algebra": [4, 6, 9, 10, 11, 13], "prime_def_lt": 4, "eq_one_or_self_of_dvd": 4, "prime_p": 4, "17": 4, "commonli": [4, 5], "prime_two": 4, "prime_thre": 4, "broader": [4, 10], "irreduc": [4, 5], "coincid": [4, 5, 9], "rise": [4, 6, 7], "dvd_mul": 4, "even_of_even_sqr": 4, "dvd_of_dvd_pow": 4, "proce": [4, 6], "profici": 4, "prefix": [4, 6, 7], "search": [4, 5, 6], "engin": 4, "hesit": 4, "mul_right_inj": 4, "heart": [4, 7], "irration": 4, "dvd_gcd": 4, "coprime_mn": 4, "sqr_eq": 4, "meq": 4, "dvd_iff_exists_eq_mul_left": 4, "two_l": 4, "le_of_dvd": 4, "approach": [4, 5, 6, 9], "quick": [4, 7, 8, 10], "ne": [4, 5], "occur": 4, "suffici": [4, 9], "primefactorslist": 4, "permut": [4, 7], "prime_of_mem_primefactorslist": 4, "prod_primefactorslist": 4, "primefactorslist_uniqu": 4, "talk": [4, 7, 8, 9, 10], "factorization_mul": 4, "mnez": 4, "nnez": 4, "factorization_pow": 4, "black": [4, 6], "box": 4, "simpa": [4, 7, 10], "nnz": 4, "nsqr_nez": 4, "eq1": 4, "eq2": 4, "add_mul_mod_self_left": 4, "mul_mod_right": 4, "count_factors_mul_of_po": 4, "succ_ne_zero": 4, "succ": [4, 6], "successor": [4, 8], "npow_nz": 4, "dvd_sub": 4, "anywai": [4, 7], "pow_eq": 4, "npowz": 4, "add_sub_cancel": 4, "understood": [4, 9], "quotient": [4, 5, 6, 9, 13], "pictur": [4, 5, 7], "mediat": 4, "headach": 4, "contend": 4, "th": [4, 8], "topic": [4, 5, 6, 7, 8], "enat": 4, "infin": [4, 9, 11], "appreci": 4, "role": [4, 5, 8, 9], "datatyp": 4, "freeli": 4, "translat": [4, 6, 7, 9], "mathematician": [4, 9], "inj": 4, "factori": 4, "fac": 4, "ih": 4, "fac_po": 4, "succ_po": 4, "dvd_fac": 4, "ipo": 4, "il": 4, "of_le_succ": 4, "dvd_mul_of_dvd_right": 4, "crude": 4, "remaind": [4, 5, 7], "pow_succ": 4, "pow_two_le_fac": 4, "finset": [4, 5, 7, 8, 9], "bigoper": [4, 5, 7], "prod": [4, 7, 8, 9, 11], "sum_range_zero": 4, "sum_range_succ": 4, "summat": 4, "prod_range_zero": 4, "prod_range_succ": 4, "deserv": 4, "danger": [4, 5], "ordinarili": [4, 5], "loop": 4, "indefinit": 4, "fix": [4, 6, 7, 8, 9], "mul_left_comm": 4, "placement": 4, "re": [4, 5], "handi": 4, "sum_id": 4, "div_eq_of_eq_mul_right": 4, "sum_sqr": 4, "mynat": 4, "thumb": 4, "decid": [4, 7, 8, 9], "preced": [4, 7], "truncat": 4, "exponenti": 4, "cut": 4, "predecessor": 4, "pred": 4, "mul": [4, 5, 6, 9], "succ_add": 4, "succ_mul": 4, "explor": [4, 8, 9], "standard": [4, 5, 6, 9], "formul": [4, 7, 9], "quirki": 4, "among": 4, "annoi": [4, 6], "h0": 4, "succ_le_succ": 4, "zero_l": [4, 5], "interval_cas": 4, "interv": [4, 9, 11], "decis": [4, 7], "procedur": [4, 6], "revert": 4, "minfac": 4, "smallest": [4, 6, 8, 9], "strong_induction_on": 4, "subsum": 4, "exists_prime_factor": 4, "np": 4, "mltn": 4, "mdvdn": 4, "mne1": 4, "mz": 4, "zero_dvd_iff": 4, "mgt2": 4, "pp": 4, "pdvd": 4, "factorial_po": 4, "dvd_factori": 4, "primes_infinit": 4, "refin": [4, 10], "ple": 4, "p_1": 4, "p_n": 4, "prod_": 4, "p_i": [4, 9], "computation": [4, 8], "test": 4, "decidableeq": [4, 8], "abandon": 4, "ourselv": [4, 6], "subset_iff": 4, "mem_int": 4, "mem_sdiff": 4, "tauto": 4, "dispens": 4, "tautologi": 4, "dvd_prod_of_mem": 4, "eq_of_dvd_of_prim": 4, "prime_q": 4, "preserv": [4, 6, 8, 9], "induction_on": 4, "singleton": 4, "prod_empti": 4, "prod_insert": 4, "mem_of_dvd_prod_prim": 4, "mem_insert": 4, "wrote": 4, "filter": [4, 10, 11, 13], "mem_filt": 4, "aim": [4, 7], "prod_po": 4, "_def": 4, "mem_": 4, "id": [4, 6, 8, 9, 10], "bounded_of_ex_finset": 4, "qk": 4, "lt_succ_of_l": 4, "le_sup": 4, "ex_finset_of_bound": 4, "decidablepr": 4, "lt_succ_iff": 4, "congruent": 4, "p_k": 4, "loss": 4, "27": 4, "mod_4_eq_3_or_mod_4_eq_3": 4, "mul_mod": 4, "mod_lt": 4, "mul_mod_mod": 4, "two_le_of_mod_4_eq_3": 4, "neq": 4, "div_dvd_of_dvd": 4, "div_lt_self": 4, "exists_prime_factor_mod_4_eq_3": 4, "mge2": 4, "mul_div_cancel": 4, "home": [4, 5], "stretch": [4, 5], "remov": [4, 9], "eras": 4, "mem_eras": 4, "readi": [4, 6, 7, 8, 9, 10], "dvd_add_iff_left": 4, "primes_mod_4_eq_3_infinit": 4, "p4": 4, "pltn": 4, "p4eq": 4, "pne3": 4, "seriou": [4, 6, 9], "feat": 4, "modern": [5, 7], "subject": 5, "consult": 5, "ann": 5, "baanen": 5, "abus": 5, "paramet": [5, 6], "broadest": 5, "possibli": 5, "constraint": [5, 9], "bundl": [5, 6, 7, 8, 9, 10], "tupl": 5, "hy": [5, 6, 7, 8], "hz": [5, 6], "mypoint1": 5, "mypoint2": 5, "mypoint3": 5, "mk": [5, 6, 7, 8, 9], "former": 5, "latter": [5, 7, 9], "quot": [5, 8, 9], "protect": 5, "add_x": 5, "addalt": 5, "eta": 5, "messier": 5, "view": [5, 6, 7, 9], "y\u2081": 5, "z\u2081": 5, "y\u2082": 5, "z\u2082": 5, "addalt_x": 5, "addalt_comm": 5, "apart": [5, 6], "effici": [5, 7, 8, 9], "scalar": [5, 6, 7, 8, 10], "smul": [5, 6, 7, 8], "smul_distrib": 5, "road": 5, "link": [5, 6], "belong": [5, 6, 9], "simplex": 5, "convinc": 5, "equilater": 5, "interior": [5, 10], "standardtwosimplex": 5, "x_nonneg": 5, "y_nonneg": 5, "z_nonneg": 5, "sum_eq": 5, "swap": 5, "swapxi": 5, "interestingli": [5, 7, 10], "midpoint": 5, "div_nonneg": 5, "weight": 5, "averag": 5, "weightedaverag": 5, "lambda_nonneg": 5, "lambda_l": 5, "fin": [5, 7, 8, 11], "standardsimplex": 5, "sum_eq_on": 5, "div_eq_mul_inv": 5, "sum_mul": 5, "sum_add_distrib": 5, "mul_sum": 5, "islinear": 5, "is_addit": 5, "preserves_mul": 5, "linf": 5, "subtyp": [5, 6, 7, 8, 9], "preal": 5, "val": 5, "sigma": [5, 11], "wherebi": [5, 9], "stdsimplex": 5, "\u03c3": [5, 7], "fst": [5, 8, 9], "snd": [5, 8, 9], "custom": 5, "robust": [5, 6], "interfac": 5, "redefin": [5, 6], "accessor": 5, "weav": 5, "rich": [5, 6], "interconnect": 5, "hierarchi": [5, 7, 8, 13], "clarifi": 5, "cdot": 5, "topolog": [5, 6, 10, 13], "mathcal": [5, 10], "proxi": 5, "bipartit": 5, "graph": [5, 8], "categori": [5, 8, 9, 10], "morphism": [5, 8, 10, 13], "basi": [5, 8, 9], "discret": 5, "inherit": [5, 6, 7, 8], "polynomi": [5, 8], "coeffici": [5, 7, 8], "dual": [5, 9], "accommod": [5, 7], "almost": [5, 6, 7, 8, 9, 11], "marriag": 5, "heaven": 5, "group\u2081": [5, 6], "inv": [5, 6], "struc": 5, "counterpart": 5, "assur": 5, "groupcat": 5, "group\u2081cat": 5, "str": 5, "capit": 5, "roman": 5, "equiv": [5, 7, 8], "tofun": [5, 6, 8], "right_inv": [5, 8], "left_inv": [5, 8], "creativ": 5, "evid": 5, "coercion": [5, 6, 7, 8, 9, 10], "omit": 5, "perm": [5, 7], "under": [5, 6, 7, 8, 9], "orient": 5, "permgroup": 5, "trans_assoc": 5, "trans_refl": 5, "refl_tran": 5, "self_trans_symm": [5, 7, 8], "grouptheori": 5, "g_1": 5, "g_2": 5, "g_3": 5, "tightli": 5, "isomorph": [5, 7, 8, 10], "Its": [5, 6], "neg": [5, 6, 9, 11], "reproduc": 5, "accompani": 5, "addgroup\u2081": 5, "scheme": 5, "addgrouppoint": 5, "arrang": 5, "mul_inv_cancel_right": 5, "achiev": [5, 6, 9], "silent": [5, 6], "regist": [5, 6, 7, 8], "grp": 5, "contextu": 5, "cue": 5, "synthes": [5, 6], "whole": [5, 8], "_inst_1": 5, "candid": 5, "group\u2082": 5, "mysquar": 5, "my_squar": 5, "remark": [5, 6], "headi": 5, "store": 5, "hasmulgroup\u2082": 5, "hasonegroup\u2082": 5, "hasinvgroup\u2082": 5, "suppli": 5, "accord": [5, 8], "capabl": 5, "chain": 5, "recent": 5, "prioriti": 5, "bad": [5, 6, 8, 9], "artifici": [5, 8], "addgroup\u2082": 5, "subtl": [5, 7, 8, 9], "configur": 5, "invisibli": [5, 6], "wise": [5, 8], "euclidean": 5, "terminologi": [5, 8], "mid": 5, "imaginari": 5, "gaussint": 5, "im": 5, "pointwis": [5, 9, 10], "root": [5, 6, 7, 8, 13], "ac": 5, "bci": 5, "adi": 5, "bd": 5, "bc": 5, "zero_def": 5, "one_def": 5, "add_def": 5, "neg_def": 5, "mul_def": 5, "zero_r": 5, "zero_im": 5, "one_r": 5, "one_im": 5, "add_r": 5, "add_im": 5, "neg_r": 5, "neg_im": 5, "mul_r": 5, "mul_im": 5, "surprisingli": [5, 6], "concept": [5, 7, 8, 9, 10], "light": 5, "bulb": 5, "skeleton": [5, 8, 9], "scari": 5, "nsmul": [5, 6], "zsmul": [5, 6], "instcommr": 5, "nsmulrec": 5, "zsmulrec": 5, "left_distrib": [5, 6], "right_distrib": [5, 6], "ext_iff": 5, "bq": 5, "archetyp": [5, 8], "eq": 5, "int": [5, 6, 7], "ediv_add_emod": 5, "emod_nonneg": 5, "emod_lt": 5, "unit": [5, 6, 9], "algorithm": 5, "conjug": [5, 7], "frac": 5, "nearest": 5, "vi": 5, "multipli": [5, 8], "emb": 5, "forth": 5, "quadrat": 5, "gaussianint": 5, "stai": 5, "face": [5, 6, 9], "machineri": [5, 6, 8, 9], "adapt": 5, "invest": 5, "pragmat": 5, "seek": 5, "heather": 5, "macbeth": 5, "eleg": 5, "div": 5, "mod": 5, "_add_mod": 5, "abs_mod": 5, "_le": 5, "emod_lt_of_po": 5, "zero_lt_two": 5, "_eq": 5, "sq_add_sq_eq_zero": 5, "linearorderedr": 5, "norm_nonneg": [5, 10], "norm_eq_zero": [5, 10], "norm_po": 5, "norm_mul": [5, 10], "conj": 5, "conj_r": 5, "conj_im": 5, "norm_conj": 5, "bespok": 5, "quad": 5, "record": [5, 6, 8], "div_def": 5, "mod_def": 5, "messi": 5, "nicer": [5, 7, 9], "norm_mod_lt": 5, "norm_y_po": 5, "sq_ab": 5, "gcongr": 5, "ediv_mul_l": 5, "le_of_mul_le_mul_right": 5, "ediv_lt_of_lt_mul": 5, "natab": 5, "coe_natabs_norm": 5, "natabs_of_nonneg": 5, "natabs_norm_mod_lt": 5, "ofnat_lt": 5, "natcast_natab": 5, "not_norm_mul_left_lt_norm": 5, "natabs_mul": 5, "le_mul_of_one_le_right": 5, "ofnat_l": 5, "add_one_le_of_lt": 5, "euclideandomain": 5, "quotient_mul_add_remainder_eq": 5, "quotient_zero": 5, "r_wellfound": 5, "remainder_lt": 5, "mul_left_not_lt": 5, "payoff": 5, "irreducible_iff_prim": 5, "studi": [6, 9], "prematur": 6, "technologi": 6, "simpler": [6, 8], "ring\u2081": 6, "gradual": [6, 9], "bottom": [6, 7, 8, 9], "endow": [6, 7, 8], "one\u2081": 6, "heavier": 6, "inferr": 6, "resolut": 6, "attribut": 6, "ensur": [6, 7, 8, 9], "self": 6, "one\u2082": 6, "usabl": 6, "silli": 6, "affect": 6, "importantli": [6, 7, 8], "habit": [6, 8], "ascript": [6, 7, 8], "messag": 6, "typeclass": [6, 8], "stuck": 6, "metavari": 6, "263": 6, "sever": [6, 8, 9, 11], "unknown": 6, "collis": 6, "builtin": 6, "\ud835\udfd9": 6, "inherit_doc": 6, "diamond": 6, "dia\u2081": 6, "dia": 6, "infixl": 6, "70": 6, "semigroup": 6, "dia_assoc": 6, "semigroup\u2081": 6, "todia\u2081": 6, "previous": 6, "semigroup\u2082": 6, "hurdl": 6, "neutral": [6, 7], "diaoneclass\u2081": 6, "one_dia": 6, "dia_on": 6, "trace": [6, 8], "ters": 6, "attempt": 6, "succe": 6, "success": 6, "set_opt": 6, "synthinst": 6, "monoid\u2081": 6, "hide": [6, 7, 9], "subtleti": [6, 7, 8], "fear": 6, "unrel": 6, "tosemigroup\u2081": 6, "todiaoneclass\u2081": 6, "monoid\u2082": 6, "toone\u2081": 6, "overlap": [6, 7], "tear": 6, "signatur": 6, "restor": 6, "optim": [6, 8, 11], "reusabl": 6, "inv\u2081": 6, "postfix": 6, "inv_dia": 6, "weak": 6, "preliminari": 6, "left_inv_eq_right_inv\u2081": 6, "hba": 6, "hac": 6, "export": 6, "inv_eq_of_dia": 6, "dia_inv": 6, "naiv": [6, 9], "duplic": 6, "to_addit": 6, "semi": [6, 7, 8], "left_inv_eq_right_inv": 6, "left_neg_eq_right_neg": 6, "whatsnew": 6, "addsemigroup\u2083": 6, "add_assoc\u2083": 6, "semigroup\u2083": 6, "mul_assoc\u2083": 6, "addmonoid\u2083": 6, "addzeroclass": 6, "monoid\u2083": 6, "muloneclass": 6, "tomuloneclass": 6, "addcommsemigroup\u2083": 6, "commsemigroup\u2083": 6, "addcommmonoid\u2083": 6, "commmonoid\u2083": 6, "addgroup\u2083": 6, "neg_add": 6, "group\u2083": 6, "inv_mul": 6, "inv_eq_of_mul": 6, "propag": 6, "attr": 6, "mul_inv": [6, 7], "mul_left_cancel\u2083": 6, "mul_right_cancel\u2083": 6, "addcommgroup\u2083": 6, "commgroup\u2083": 6, "demonstr": [6, 9], "semir": [6, 7], "opposit": [6, 9], "gain": 6, "besid": 6, "parent": 6, "ring\u2083": 6, "mulzeroclass": 6, "toaddgroup\u2083": 6, "mayb": 6, "claus": 6, "le\u2081": 6, "50": 6, "\u2081": 6, "preorder\u2081": 6, "partialorder\u2081": 6, "orderedcommmonoid\u2081": 6, "modul": [6, 7, 8], "pretend": [6, 8], "smul\u2083": 6, "infixr": 6, "73": 6, "module\u2081": 6, "zero_smul": 6, "one_smul": [6, 7], "mul_smul": [6, 7], "add_smul": [6, 7, 8], "smul_add": [6, 8], "surpris": 6, "toaddcommgroup\u2083": 6, "inst": 6, "module\u2083": 6, "hunt": [6, 8], "unspecifi": [6, 8], "embark": 6, "quest": 6, "huge": 6, "trap": 6, "refus": [6, 9], "tosmul\u2083": 6, "inst_1": 6, "safe": [6, 7], "selfmodul": 6, "invert": [6, 7, 8], "nsmul\u2081": 6, "zsmul\u2081": 6, "ofnat": 6, "negsucc": 6, "abgrpmodul": 6, "failur": 6, "synth": 6, "indirect": 6, "path": 6, "thank": 6, "offend": 6, "poor": 6, "forget": 6, "http": 6, "inria": 6, "hal": 6, "scienc": 6, "02463336v2": 6, "modifi": 6, "addmonoid\u2084": 6, "nsmul_zero": 6, "nsmul_succ": 6, "mysmul": 6, "stori": [6, 8], "incorpor": 6, "lt\u2081": 6, "comparison": 6, "ismonoidhom\u2081": 6, "unpleas": [6, 9], "chose": 6, "ismonoidhom\u2082": 6, "map_on": [6, 7], "map_mul": [6, 7, 8], "tempt": 6, "higher": 6, "unif": 6, "psycholog": 6, "rare": 6, "adject": 6, "bare": [6, 8], "noun": 6, "argu": 6, "continuous_id": [6, 9], "primari": 6, "monoidhom\u2081": 6, "coefun": 6, "coerc": [6, 7, 8], "coe": 6, "addmonoidhom\u2081": 6, "addmonoid": [6, 7], "map_zero": [6, 7], "map_add": [6, 7, 8, 10], "ringhom\u2081": 6, "minor": [6, 10], "tomonoidhom\u2081": 6, "juggl": 6, "monoidhomclass\u2081": 6, "badinst": 6, "wouldn": 6, "priori": [6, 8], "boil": 6, "hopelessli": 6, "checksynthord": 6, "random": 6, "deduc": [6, 7, 9], "outparam": 6, "trigger": [6, 8], "retri": 6, "monoidhomclass\u2082": 6, "promis": [6, 8, 9], "map_inv_of_inv": 6, "got": 6, "presenc": 6, "layer": [6, 9], "dfunlik": 6, "dfun": 6, "monoidhomclass": 6, "monoidhomclass\u2083": 6, "coe_inject": 6, "stop": 6, "ringhomclass\u2083": 6, "ringhom": [6, 7], "algebrahom": 6, "ve": [6, 9], "primarili": [6, 7, 9], "unbundl": 6, "orderpreshom": 6, "le_of_l": 6, "orderpresmonoidhom": 6, "orderpreshomclass": 6, "subgroup": 6, "subr": 6, "reus": 6, "led": 6, "descend": [6, 7], "break": 6, "barrier": 6, "setlik": 6, "wrap": [6, 9], "submonoid\u2081": 6, "submonoid": [6, 7], "mul_mem": [6, 7], "one_mem": [6, 7], "tackl": 6, "setco": 6, "submonoid\u2081monoid": 6, "destructur": 6, "binder": 6, "submonoidclass\u2081": 6, "subgroup\u2081": 6, "subgroupclass\u2081": 6, "subobject": 6, "s\u2081": 6, "s\u2082": 6, "shame": 6, "across": 6, "weird": [6, 9], "distract": 6, "emphas": [6, 7], "anecdot": 6, "devic": 6, "hasquoti": 6, "regular": [6, 9], "ascii": 6, "setoid": [6, 7], "commmonoid": 6, "iseqv": 6, "hw": 6, "quotientmonoid": 6, "map\u2082": 6, "treatment": 7, "constantli": 7, "review": [7, 9], "contort": 7, "verbatim": 7, "safer": 7, "friendli": 7, "proceed": 7, "mostli": 7, "comm": 7, "addcommmonoid": [7, 8], "monoidhom": 7, "addmonoidhom": 7, "packag": [7, 8], "unfortun": 7, "consequ": 7, "comp": [7, 8, 9], "map_inv": 7, "enforc": 7, "sent": [7, 9], "mulequiv": 7, "addequiv": 7, "ulequiv": 7, "projector": 7, "ofbiject": [7, 8], "closur": [7, 8, 9], "inv_mem": 7, "issubgroup": 7, "addsubgroup": 7, "add_mem": [7, 8], "zero_mem": [7, 8], "neg_mem": 7, "inferinst": [7, 8], "benefit": [7, 8], "amount": [7, 8], "sup_eq_closur": 7, "mem_bot": [7, 8], "ambient": 7, "ty": 7, "comap": [7, 8, 9], "pushforward": [7, 9], "mem_map": [7, 8], "mem_comap": [7, 8], "kernel": [7, 8], "ker": [7, 8], "mem_ker": [7, 8], "mem_rang": 7, "\u03c6": [7, 8, 9], "hst": 7, "\u03c8": [7, 8], "homomorph": 7, "lagrang": 7, "sylow": 7, "corner": 7, "nonconstruct": 7, "card": 7, "index_mul_card": 7, "hdvd": 7, "exists_subgroup_card_pow_prim": 7, "corollari": 7, "eq_bot_iff_card": 7, "eq_bot_iff_foral": 7, "card_eq_one_iff_exist": 7, "card_dvd_of_l": 7, "inf_bot_of_coprim": 7, "mathfrak": 7, "_n": 7, "cycl": 7, "iscycl": 7, "closure_iscycl": 7, "cyclic": 7, "freegroup": 7, "induct": [7, 8, 9, 13], "myelement": 7, "gave": [7, 9], "embodi": 7, "lift": [7, 8], "send": [7, 8, 11], "mymorph": 7, "cube": 7, "presentedgroup": 7, "normal": 7, "somehow": [7, 8], "creation": 7, "mygroup": 7, "feed": 7, "togroup": 7, "mymap": 7, "compat_mymap": 7, "mynewmorph": 7, "mulact": 7, "downsid": [7, 8], "setup": [7, 8], "synonym": 7, "groupact": 7, "addact": 7, "\u1d65": [7, 8], "affin": 7, "add_vadd": 7, "topermhom": 7, "caylei": [7, 8], "embed": 7, "cayleyisomorph": 7, "subgroupofmulact": 7, "partit": 7, "orbit": 7, "orbitrel": 7, "global": [7, 9], "\u03c9": 7, "selfequivsigmaorbit": 7, "fintyp": [7, 8, 9], "card_congr": 7, "card_sigma": 7, "furthermor": 7, "stabil": 7, "orbitequivquotientstabil": 7, "groupequivquotientprodsubgroup": 7, "conjugate_on": 7, "quotientgroup": 7, "clue": 7, "onto": [7, 8], "quotientkerequivrang": 7, "pullback": [7, 9], "quotientmulequivofeq": 7, "seri": 7, "card_po": 7, "index_eq_card": 7, "eq_of_mul_eq_mul_right": 7, "aux_card_eq": 7, "bijective_iff_injective_and_card": 7, "ker_eq_bot_iff": 7, "ker_restrict": 7, "iso\u2081": 7, "g\u2080": 7, "g\u2081": 7, "g\u2082": 7, "iso\u2082": 7, "prodcongr": 7, "finaliso": 7, "exot": [7, 9], "commsemir": [7, 8], "doubli": 7, "mislead": 7, "tradition": 7, "taught": 7, "promin": 7, "isunit": 7, "m\u02e3": 7, "mainli": 7, "mkofmuleqon": 7, "\u2124\u02e3": 7, "units_eq_one_or": 7, "r\u02e3": 7, "s\u02e3": 7, "ringequiv": 7, "toward": 7, "geometri": 7, "submodul": [7, 8], "eq_zero_iff_mem": 7, "mem_sup": [7, 8], "mul_le_left": 7, "mul_le_right": 7, "mul_le_inf": 7, "quotientmap": 7, "quotequivofeq": 7, "chines": 7, "\u03c0": [7, 8, 9, 10], "font": 7, "\u03b9": [7, 8, 9, 10, 11], "iscoprim": [7, 8], "quotientinfringequivpiquoti": 7, "zmod": 7, "pinot": 7, "prodequivpi": 7, "pi": [7, 8, 9], "ker_pi_quotient_mk": 7, "chinesemap": 7, "proven": [7, 8], "chinesemap_mk": 7, "famili": [7, 8, 9, 10], "injective_lift_iff": 7, "chinesemap_inj": 7, "maxim": 7, "iscoprime_iff_add": 7, "iscoprime_iff_exist": 7, "iscoprime_iff_sup_eq": 7, "iscoprime_iff_codisjoint": 7, "opportun": [7, 9], "mem_insert_of_mem": 7, "mem_insert_self": 7, "iscoprime_inf": 7, "simp_rw": 7, "iinf_insert": 7, "one_eq_top": 7, "eq_top_iff": 7, "chinesemap_surj": 7, "hi": 7, "mk_surject": 7, "\u1d9c": 7, "he": 7, "chineseiso": 7, "encod": [7, 11], "algebramap": 7, "alghom": 7, "\u2090": 7, "endomorph": [7, 13], "univari": 7, "indetermin": 7, "crucial": [7, 8, 9], "bodi": 7, "map_pow": 7, "coeff": 7, "degre": 7, "natdegre": 7, "withbot": 7, "absorb": 7, "formula": [7, 11], "nozerodivisor": 7, "degree_mul": 7, "hp": [7, 9], "hq": [7, 9], "natdegree_mul": 7, "natdegree_comp": 7, "evalu": [7, 8], "isroot": [7, 8], "vanish": [7, 8], "count": 7, "pain": 7, "multiset": 7, "roots_x_sub_c": 7, "aeval": [7, 8], "aroot": 7, "caveat": 7, "aroots_def": 7, "c_mul": 7, "c_neg": 7, "linear_combin": 7, "p_ne_zero": 7, "apply_fun": 7, "roots_mul": 7, "alembert": 7, "gauss": 7, "isalgclos": 7, "eval\u2082": 7, "ofrealhom": 7, "multivari": 7, "briefli": 7, "mvpolynomi": 7, "circl": 7, "circleequ": 7, "coordin": [7, 8], "9": 8, "eccentr": 8, "spell": [8, 9], "synthesi": 8, "smul_comm": 8, "advanc": 8, "medit": 8, "captur": 8, "ideal": 8, "\u2097": 8, "az": 8, "map_smul": [8, 10], "linearmap": 8, "\u03b8": 8, "action": 8, "attach": [8, 9], "wonder": 8, "etc": [8, 9], "lsmul": 8, "linearequiv": 8, "announc": 8, "binary_product": 8, "parallel": 8, "prodmap": 8, "aka": [8, 9], "coproduct": 8, "coprod": 8, "coprod_inl": 8, "coprod_inr": 8, "directsum": 8, "accid": 8, "assembl": [8, 9], "summand": 8, "tomodul": 8, "proj": 8, "lof": 8, "linearequivfunonfintyp": 8, "smul_mem": 8, "issubmodul": 8, "supersed": 8, "mem_preimag": 8, "span_union": 8, "iscompl": 8, "isintern": 8, "sup_eq_top": 8, "inf_eq_bot": 8, "submodule_isup_eq_top": 8, "pairwis": [8, 11], "hij": 8, "submodule_independ": 8, "pairwisedisjoint": 8, "eq_bot": 8, "isinternal_submodule_iff_independent_and_isup_eq_top": 8, "extern": 8, "coelinearmap": 8, "span_l": 8, "galoisinsert": 8, "gi": 8, "span_induct": 8, "stabl": 8, "span_eq": 8, "awkward": 8, "contributor": 8, "range_eq_map": 8, "comap_bot": 8, "flavor": 8, "elabor": [8, 9], "ker_eq_bot": 8, "range_eq_top": 8, "mem_map_of_mem": 8, "mkq": 8, "liftq": 8, "ker_mkq": 8, "range_mkq": 8, "h\u03c6": 8, "mapq": 8, "quotkerequivrang": 8, "comapmkqreliso": 8, "map_comap_eq": 8, "comap_map_eq": 8, "eigenvalu": 8, "eigenvector": 8, "mul_eq_comp": 8, "aeval_x": 8, "pq": 8, "eq_bot_iff": 8, "mem_inf": 8, "add_mem_sup": 8, "mul_appli": 8, "ker_le_ker_comp": 8, "eigenspac": 8, "aid": 8, "haseigenvector": 8, "eigenspace_def": 8, "haseigenvalu": 8, "exists_haseigenvector": 8, "hv": 8, "haseigenvalue_of_haseigenvector": 8, "minim": 8, "minpoli": 8, "isroot_of_haseigenvalu": 8, "finitedimension": [8, 10, 11], "haseigenvalue_iff_isroot": 8, "hamilton": 8, "charpoli": 8, "aeval_self_charpoli": 8, "sage": 8, "arrai": 8, "virtual": 8, "machin": 8, "matrix": 8, "row": 8, "column": 8, "resp": 8, "vecmul": 8, "mulvec": 8, "size": 8, "col": 8, "transpos": 8, "11": [8, 10], "\u1d40": 8, "det": [8, 11], "consider": 8, "trust": 8, "counter": 8, "adjug": 8, "cramer": 8, "inv_def": 8, "inv_mul_of_invert": 8, "invertibleofisunitdet": 8, "one_fin_two": 8, "adjac": 8, "meaning": 8, "fin_cas": 8, "lose": 8, "secretli": 8, "vandermond": 8, "linearli": 8, "repr": 8, "tortuou": 8, "useless": 8, "b_indep": 8, "linearindepend": 8, "b_span": 8, "mk_appli": 8, "finsupp": 8, "basissingleon": 8, "unneed": 8, "basisfun": 8, "sum_repr": 8, "account": 8, "linearcombin": 8, "linearcombination_apply_of_mem_support": 8, "linearcombination_repr": 8, "despit": 8, "constr": 8, "constr_basi": 8, "characterist": 8, "identif": 8, "tomatrix": 8, "tomatrix_mulvec_repr": 8, "shouldn": [8, 9], "tomatrix_comp": 8, "id_comp": 8, "comp_id": 8, "tomatrix_id": 8, "det_mul": 8, "det_on": 8, "dimension": [8, 10, 11], "finrank": 8, "finrank_fin_fun": 8, "finrank_self": 8, "finrank_real_complex": 8, "finrank_pos_iff": 8, "fine": 8, "of_fintype_basi": 8, "fintypebasisindex": 8, "finrank_sup_add_finrank_inf_eq": 8, "finrank_l": 8, "earli": 8, "rank": 8, "russel": 8, "paradox": [8, 9], "zeroth": 8, "u_n": 8, "u_2": 8, "mk_eq_mk_of_basi": 8, "finrank_eq_rank": 8, "calculu": [9, 11, 13], "quantiti": 9, "begun": 9, "x\u2080": [9, 10], "convention": 9, "eight": 9, "varieti": 9, "wish": 9, "64": 9, "y\u2080": 9, "z\u2080": 9, "paragraph": 9, "512": 9, "bourbaki": 9, "dualli": 9, "neighborhood": 9, "attop": [9, 11], "\ud835\udcdd": [9, 10, 11], "\ud835\udce4": 9, "entourag": 9, "\u03bc": [9, 11], "ae": [9, 11], "univ_set": 9, "sets_of_superset": 9, "inter_set": 9, "blur": 9, "princip": 9, "\ud835\udcdf": 9, "x_0": 9, "ioo": [9, 10], "tendsto\u2081": 9, "tendsto": [9, 11], "lim_": 9, "abstractli": 9, "salient": 9, "f_": 9, "tendsto\u2082": 9, "via": 9, "leverag": 9, "map_mono": 9, "map_map": 9, "shot": 9, "map_le_iff_le_comap": 9, "contravari": 9, "comap_comap": 9, "plane": 9, "\u02e2": 9, "nhds_prod_eq": 9, "aforement": 9, "le_inf_iff": 9, "prohibit": 9, "precondit": 9, "nebot": 9, "tour": [9, 10], "claim": 9, "recaptur": 9, "superfici": 9, "stronger": 9, "flexibl": 9, "hasbasi": 9, "nhds_basis_ioo_po": 9, "tendsto_iff": 9, "reformul": 9, "ici": 9, "attop_basi": 9, "knew": 9, "n_p": 9, "n_q": 9, "tiresom": 9, "\u1da0": [9, 10, 11], "superscript": 9, "eventuallyeq": 9, "tendsto_congr": 9, "of_foral": 9, "mono": 9, "item": 9, "filter_upward": 9, "hr": 9, "occasion": 9, "frequent": 9, "sophist": 9, "mem_closure_of_tendsto": 9, "clusterpt": 9, "mem_closure_iff_clusterpt": 9, "le_principal_iff": 9, "nebot_of_l": 9, "hux": 9, "hum": 9, "dist_eq_zero": 9, "emetricspac": 9, "pseudometricspac": 9, "pseudoemetricspac": 9, "journei": 9, "recast": 9, "tendsto_attop": 9, "continuous_iff": 9, "devot": 9, "uncurri": 9, "slow": 9, "continuous_fst": 9, "prod_mk": 9, "continuous_snd": 9, "continuous_dist": 9, "clunki": 9, "heavili": 9, "prod_map": 9, "sad": 9, "border": 9, "obfusc": 9, "continuous_pow": 9, "continuousat": [9, 11], "continuousat_iff": 9, "geometr": 9, "closedbal": 9, "sign": 9, "radiu": 9, "mem_ball_self": 9, "mem_closedball_self": 9, "isopen": 9, "isopen_iff": 9, "Their": [9, 10], "isclos": [9, 10], "s\u1d9c": [9, 11], "isopen_compl_iff": 9, "hu": [9, 10], "mem_of_tendsto": 9, "mem_closure_iff": 9, "mem_closure_iff_seq_limit": 9, "nhds_basis_bal": 9, "nhds_basis_closedbal": 9, "mem_iff": 9, "segment": [9, 11], "somewher": 9, "continuouson": [9, 10], "minimum": 9, "iscompact": 9, "icc": [9, 10], "iscompact_icc": 9, "strictmono": 9, "tendsto_subseq": 9, "exists_isminon": 9, "exists_ismaxon": 9, "compactspac": 9, "iscompact_univ": 9, "cauchi": 9, "uniformcontinu": 9, "uniformcontinuous_iff": 9, "clearli": 9, "isclosed_l": [9, 10], "eq_empty_or_nonempti": 9, "attain": 9, "cauchyseq": 9, "cauchyseq_iff": 9, "completespac": [9, 10, 11], "cauchyseq_tendsto_of_complet": 9, "criterion": 9, "tendsto_pow_attop_nhds_zero_of_lt_on": 9, "dist_le_range_sum_dist": 9, "cauchyseq_of_le_geometric_two": 9, "\u03b5_po": [9, 10], "le_iff_exists_add": 9, "boss": 9, "bair": [9, 10], "exclam": 9, "rec_on": 9, "ho": 9, "hd": 9, "dens": 9, "densiti": 9, "\u03b4po": 9, "hpo": 9, "hball": 9, "mem_closure_iff_nhds_basi": 9, "recon": 9, "rpo": 9, "rb": 9, "incl": 9, "cdist": 9, "ylim": 9, "yball": 9, "categor": 9, "topologicalspac": [9, 10], "isopen_univ": 9, "isopen_empti": 9, "isopen_iunion": 9, "isopen_iinter_of_finit": 9, "continuous_def": 9, "filteri": 9, "mem_nhds_iff": 9, "digress": 9, "pure_le_nhd": 9, "self_of_nhd": 9, "eventually_eventually_nhd": 9, "mkofnhd": 9, "nhds_mkofnhd": 9, "functori": 9, "induc": 9, "sensibl": 9, "uncount": 9, "relatedli": 9, "coinduc": 9, "t_x": 9, "t_y": 9, "coinduced_le_iff_le_induc": 9, "covari": 9, "coinduced_compos": 9, "induced_compos": 9, "focus": 9, "nhd": 9, "recov": 9, "continuous_iff_coinduced_l": 9, "g_": 9, "t_z": 9, "wasn": 9, "t_": 9, "x_i": 9, "price": 9, "patholog": 9, "t2space": 9, "hausdorff": 9, "t3space": 9, "regularspac": 9, "tendsto_nhds_uniqu": 9, "closed_nhds_basi": 9, "nhds_basis_open": 9, "t_3": 9, "denseinduc": 9, "continuousat_extend": 9, "funni": 9, "_in": 9, "nhds_induc": 9, "fortiori": 9, "f_cont": 9, "tendsto_right_iff": 9, "firstcountabletopologi": 9, "cluster": 9, "hfx": 9, "push_pul": 9, "of_map": 9, "f_ne": 9, "f_le": 9, "map_eq": 9, "hne": 9, "hle": 9, "huo": 9, "hsu": 9, "elim_finite_subcov": 9, "introductori": 10, "hasderivat": [10, 11], "hasderivat_sin": 10, "differentiableat": 10, "inconveni": 10, "deriv_zero_of_not_differentiableat": 10, "deriv_add": 10, "islocalmin": 10, "deriv_eq_zero": 10, "roll": 10, "weirder": 10, "hab": 10, "hfc": 10, "hfi": 10, "exists_deriv_eq_zero": 10, "differentiableon": 10, "exists_deriv_eq_slop": 10, "normedaddcommgroup": [10, 11], "norm_add_l": 10, "infer_inst": [10, 11], "normedspac": [10, 11], "normedaddgroup": 10, "stipul": 10, "norm_smul": 10, "banach": [10, 11], "\ud835\udd5c": [10, 11], "nontriviallynormedfield": [10, 11], "normedfield": 10, "exists_one_lt_norm": 10, "continuouslinearmap": 10, "cont": 10, "le_opnorm": 10, "hmp": 10, "hm": 10, "opnorm_le_bound": 10, "steinhau": 10, "bounded": 10, "uniformli": 10, "nonempty_interior_of_iunion_of_clos": 10, "continuous_linear_map": 10, "opnorm_le_of_shel": 10, "interior_subset": 10, "interior_iinter_subset": 10, "hc": 10, "h\u03b5": 10, "real_norm_l": 10, "\u03b5k_po": 10, "o": 10, "normedgroup": 10, "isbigowith": 10, "isbigowith_iff": 10, "isbigo_iff_isbigowith": 10, "islittleo_iff_forall_isbigowith": 10, "hasfderivat": 10, "fderiv": 10, "fr\u00e9chet": 10, "hasfderivatfilter_iff_islittleo": 10, "hff": 10, "iter": 10, "multilinear": 10, "withtop": 10, "infti": 10, "contdiff": 10, "iteratedfderiv": 10, "contdiff_iff_continuous_differenti": 10, "stricter": 10, "hasstrictfderivat": 10, "\ud835\udd42": 10, "rclike": 10, "contdiffat": 10, "localinvers": 10, "eventually_left_invers": 10, "eventually_right_invers": 10, "to_localinvers": 10, "hasfderivwithinat": [10, 11], "hasfderivatfilt": 10, "measuretheori": 11, "intervalintegr": 11, "integral_id": 11, "integral_one_div": 11, "differenti": [11, 13], "integral_hasstrictderivat_right": 11, "stronglymeasurableatfilt": 11, "volum": 11, "integral_eq_sub_of_hasderivat": 11, "convolut": 11, "bochner": 11, "lebesgu": 11, "measurablespac": 11, "countabl": 11, "measurableset": 11, "compl": 11, "iunion": 11, "iinter": 11, "measure_eq_iinf": 11, "measure_iunion_l": 11, "hmea": 11, "hdi": 11, "m_iunion": 11, "\u1d50": 11, "integral_add": 11, "ennreal": 11, "toreal": 11, "setintegral_const": 11, "domin": 11, "converg": [11, 13], "aestronglymeasur": 11, "hbound": 11, "hlim": 11, "tendsto_integral_of_dominated_converg": 11, "fubini": 11, "sigmafinit": 11, "\u03bd": 11, "integral_prod": 11, "bilinear": 11, "borelspac": 11, "isaddhaarmeasur": 11, "invari": 11, "mass": 11, "compact": 11, "h_inj": 11, "integral_image_eq_integral_abs_det_fderiv_smul": 11, "overview": 13, "schr\u00f6der": 13, "bernstein": 13, "irrat": 13, "dimens": 13}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"introduct": 0, "get": 0, "start": 0, "overview": 0, "basic": [1, 6], "calcul": 1, "prove": 1, "ident": 1, "algebra": [1, 5, 7, 8], "structur": [1, 5, 8], "us": 1, "theorem": [1, 3], "lemma": 1, "more": 1, "exampl": 1, "appli": 1, "rw": 1, "fact": 1, "about": 1, "logic": 2, "implic": 2, "univers": 2, "quantifi": 2, "The": [2, 3], "existenti": 2, "negat": 2, "conjunct": 2, "iff": 2, "disjunct": 2, "sequenc": 2, "converg": [2, 9], "set": [3, 8, 9], "function": [3, 9], "schr\u00f6der": 3, "bernstein": 3, "elementari": [4, 10, 11], "number": 4, "theori": [4, 11], "irrat": 4, "root": 4, "induct": 4, "recurs": 4, "infinit": 4, "mani": 4, "prime": 4, "defin": 5, "build": 5, "gaussian": 5, "integ": 5, "hierarchi": 6, "morphism": [6, 7], "sub": 6, "object": 6, "group": 7, "ring": 7, "monoid": 7, "subgroup": 7, "concret": 7, "action": 7, "quotient": [7, 8], "unit": 7, "subr": 7, "ideal": 7, "polynomi": 7, "linear": [8, 10], "vector": 8, "space": [8, 9, 10], "map": [8, 10], "sum": 8, "product": 8, "subspac": 8, "complet": [8, 9], "lattic": 8, "intern": 8, "direct": 8, "span": 8, "push": 8, "pull": 8, "endomorph": 8, "matric": 8, "base": 8, "dimens": 8, "topologi": 9, "filter": 9, "metric": 9, "continu": [9, 10], "ball": 9, "open": 9, "close": 9, "compact": 9, "uniformli": 9, "topolog": 9, "fundament": 9, "separ": 9, "countabl": 9, "differenti": 10, "calculu": 10, "norm": 10, "asymptot": 10, "comparison": 10, "integr": 11, "measur": 11, "index": 12, "mathemat": 13, "lean": 13}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx": 60}, "alltitles": {"Introduction": [[0, "introduction"]], "Getting Started": [[0, "getting-started"]], "Overview": [[0, "overview"]], "Basics": [[1, "basics"], [6, "basics"]], "Calculating": [[1, "calculating"]], "Proving Identities in Algebraic Structures": [[1, "proving-identities-in-algebraic-structures"]], "Using Theorems and Lemmas": [[1, "using-theorems-and-lemmas"]], "More examples using apply and rw": [[1, "more-examples-using-apply-and-rw"]], "Proving Facts about Algebraic Structures": [[1, "proving-facts-about-algebraic-structures"]], "Logic": [[2, "logic"]], "Implication and the Universal Quantifier": [[2, "implication-and-the-universal-quantifier"]], "The Existential Quantifier": [[2, "the-existential-quantifier"]], "Negation": [[2, "negation"]], "Conjunction and Iff": [[2, "conjunction-and-iff"]], "Disjunction": [[2, "disjunction"]], "Sequences and Convergence": [[2, "sequences-and-convergence"]], "Sets and Functions": [[3, "sets-and-functions"]], "Sets": [[3, "sets"]], "Functions": [[3, "functions"]], "The Schr\u00f6der-Bernstein Theorem": [[3, "the-schroder-bernstein-theorem"]], "Elementary Number Theory": [[4, "elementary-number-theory"]], "Irrational Roots": [[4, "irrational-roots"]], "Induction and Recursion": [[4, "induction-and-recursion"]], "Infinitely Many Primes": [[4, "infinitely-many-primes"]], "Structures": [[5, "structures"]], "Defining structures": [[5, "defining-structures"]], "Algebraic Structures": [[5, "algebraic-structures"]], "Building the Gaussian Integers": [[5, "building-the-gaussian-integers"]], "Hierarchies": [[6, "hierarchies"]], "Morphisms": [[6, "morphisms"]], "Sub-objects": [[6, "sub-objects"]], "Groups and Rings": [[7, "groups-and-rings"]], "Monoids and Groups": [[7, "monoids-and-groups"]], "Monoids and their morphisms": [[7, "monoids-and-their-morphisms"]], "Groups and their morphisms": [[7, "groups-and-their-morphisms"]], "Subgroups": [[7, "subgroups"]], "Concrete groups": [[7, "concrete-groups"]], "Group actions": [[7, "group-actions"]], "Quotient groups": [[7, "quotient-groups"]], "Rings": [[7, "rings"]], "Rings, their units, morphisms and subrings": [[7, "rings-their-units-morphisms-and-subrings"]], "Ideals and quotients": [[7, "ideals-and-quotients"]], "Algebras and polynomials": [[7, "algebras-and-polynomials"]], "Linear algebra": [[8, "linear-algebra"]], "Vector spaces and linear maps": [[8, "vector-spaces-and-linear-maps"]], "Vector spaces": [[8, "vector-spaces"]], "Linear maps": [[8, "linear-maps"]], "Sums and products of vector spaces": [[8, "sums-and-products-of-vector-spaces"]], "Subspaces and quotients": [[8, "subspaces-and-quotients"]], "Subspaces": [[8, "subspaces"]], "Complete lattice structure and internal direct sums": [[8, "complete-lattice-structure-and-internal-direct-sums"]], "Subspace spanned by a set": [[8, "subspace-spanned-by-a-set"]], "Pushing and pulling subspaces": [[8, "pushing-and-pulling-subspaces"]], "Quotient spaces": [[8, "quotient-spaces"]], "Endomorphisms": [[8, "endomorphisms"]], "Matrices, bases and dimension": [[8, "matrices-bases-and-dimension"]], "Matrices": [[8, "matrices"]], "Bases": [[8, "bases"]], "Dimension": [[8, "dimension"]], "Topology": [[9, "index-0"]], "Filters": [[9, "filters"]], "Metric spaces": [[9, "metric-spaces"]], "Convergence and continuity": [[9, "convergence-and-continuity"]], "Balls, open sets and closed sets": [[9, "balls-open-sets-and-closed-sets"]], "Compactness": [[9, "compactness"], [9, "id5"]], "Uniformly continuous functions": [[9, "uniformly-continuous-functions"]], "Completeness": [[9, "completeness"]], "Topological spaces": [[9, "topological-spaces"]], "Fundamentals": [[9, "fundamentals"]], "Separation and countability": [[9, "separation-and-countability"]], "Differential Calculus": [[10, "index-0"]], "Elementary Differential Calculus": [[10, "elementary-differential-calculus"]], "Differential Calculus in Normed Spaces": [[10, "differential-calculus-in-normed-spaces"]], "Normed spaces": [[10, "id3"]], "Continuous linear maps": [[10, "continuous-linear-maps"]], "Asymptotic comparisons": [[10, "asymptotic-comparisons"]], "Differentiability": [[10, "differentiability"]], "Integration and Measure Theory": [[11, "index-0"]], "Elementary Integration": [[11, "elementary-integration"]], "Measure Theory": [[11, "measure-theory"]], "Integration": [[11, "integration"]], "Index": [[12, "index"]], "Mathematics in Lean": [[13, "mathematics-in-lean"]]}, "indexentries": {"check": [[0, "index-0"]], "commands": [[0, "index-0"]], "abel": [[1, "index-15"], [7, "index-3"]], "absolute value": [[1, "index-24"]], "apply": [[1, "index-12"], [1, "index-17"]], "calc": [[1, "index-3"]], "command": [[1, "index-9"]], "commutative ring": [[1, "index-8"]], "definitional equality": [[1, "index-13"]], "divisibility": [[1, "index-25"]], "exact": [[1, "index-12"], [1, "index-17"], [1, "index-5"]], "exponential": [[1, "index-19"]], "gcd": [[1, "index-26"]], "goal": [[1, "index-2"]], "group": [[1, "index-15"], [7, "index-2"]], "group (algebraic structure)": [[1, "index-14"], [7, "index-1"]], "group (tactic)": [[1, "index-15"], [7, "index-2"]], "have": [[1, "index-11"], [2, "index-12"]], "implicit argument": [[1, "index-10"]], "inequalities": [[1, "index-16"]], "lattice": [[1, "index-28"]], "lcm": [[1, "index-26"]], "linarith": [[1, "index-18"]], "local context": [[1, "index-2"]], "logarithm": [[1, "index-19"]], "max": [[1, "index-21"]], "metric space": [[1, "index-30"], [9, "index-2"]], "min": [[1, "index-21"]], "namespace": [[1, "index-9"]], "noncomm_ring": [[1, "index-15"]], "norm_num": [[1, "index-20"]], "open": [[1, "index-9"]], "order relation": [[1, "index-27"]], "partial order": [[1, "index-27"]], "proof state": [[1, "index-2"]], "real numbers": [[1, "index-1"]], "refl and reflexivity": [[1, "index-13"]], "reflexivity": [[1, "index-13"]], "repeat": [[1, "index-23"]], "rewrite": [[1, "index-0"]], "rfl": [[1, "index-13"]], "ring": [[1, "index-6"]], "ring (algebraic structure)": [[1, "index-7"], [7, "index-4"]], "ring (tactic)": [[1, "index-6"]], "rw": [[1, "index-0"], [1, "index-4"]], "rw and rewrite": [[1, "index-0"], [1, "index-4"]], "show": [[1, "index-22"]], "tactics": [[1, "index-0"], [1, "index-11"], [1, "index-12"], [1, "index-13"], [1, "index-15"], [1, "index-17"], [1, "index-18"], [1, "index-20"], [1, "index-22"], [1, "index-23"], [1, "index-29"], [1, "index-3"], [1, "index-4"], [1, "index-5"], [1, "index-6"], [2, "index-0"], [2, "index-11"], [2, "index-12"], [2, "index-13"], [2, "index-14"], [2, "index-15"], [2, "index-16"], [2, "index-17"], [2, "index-18"], [2, "index-19"], [2, "index-2"], [2, "index-20"], [2, "index-21"], [2, "index-23"], [2, "index-24"], [2, "index-25"], [2, "index-26"], [2, "index-4"], [2, "index-6"], [2, "index-8"], [2, "index-9"], [3, "index-1"], [3, "index-2"], [4, "index-0"], [7, "index-2"], [7, "index-3"], [9, "index-3"]], "trans": [[1, "index-29"]], "absurd": [[2, "index-17"]], "anonymous constructor": [[2, "index-7"]], "assumption": [[2, "index-19"]], "by_cases": [[2, "index-23"]], "by_contra": [[2, "index-14"]], "by_contra and by_contradiction": [[2, "index-14"]], "cases": [[2, "index-8"]], "change": [[2, "index-2"]], "congr": [[2, "index-25"]], "constructor": [[2, "index-18"]], "contradiction": [[2, "index-17"]], "contrapose": [[2, "index-16"]], "convert": [[2, "index-26"]], "dsimp": [[2, "index-2"]], "erw": [[2, "index-4"]], "excluded middle": [[2, "index-22"]], "exfalso": [[2, "index-17"]], "ext": [[2, "index-24"]], "extensionality": [[2, "index-24"]], "field_simp": [[2, "index-11"]], "from": [[2, "index-12"]], "injective function": [[2, "index-5"]], "intro": [[2, "index-0"]], "lambda abstraction": [[2, "index-1"]], "left": [[2, "index-21"]], "let": [[2, "index-13"]], "monotone function": [[2, "index-3"]], "push_neg": [[2, "index-15"]], "rcases": [[2, "index-9"]], "right": [[2, "index-21"]], "rintro": [[2, "index-9"]], "simp": [[2, "index-20"], [3, "index-1"]], "surjective function": [[2, "index-10"]], "this": [[2, "index-12"]], "use": [[2, "index-6"]], "bounded quantifiers": [[3, "index-3"]], "rwa": [[3, "index-2"]], "set operations": [[3, "index-0"]], "decide": [[4, "index-0"]], "monoid": [[7, "index-0"]], "linear map": [[8, "index-1"]], "matrices": [[8, "index-3"]], "vector space": [[8, "index-0"]], "vector subspace": [[8, "index-2"]], "filter": [[9, "index-1"]], "continuity": [[9, "index-3"]], "topological space": [[9, "index-4"]], "topology": [[9, "index-0"]], "differential calculus": [[10, "index-0"]], "elementary calculus": [[10, "index-1"]], "normed space": [[10, "index-2"]], "integration": [[11, "index-0"], [11, "index-1"]], "measure theory": [[11, "index-2"]]}}) Search.setIndex({"alltitles": {"Algebraic Structures": [[5, "algebraic-structures"]], "Algebras and polynomials": [[7, "algebras-and-polynomials"]], "Asymptotic comparisons": [[10, "asymptotic-comparisons"]], "Balls, open sets and closed sets": [[9, "balls-open-sets-and-closed-sets"]], "Bases": [[8, "bases"]], "Basics": [[1, null], [6, "basics"]], "Building the Gaussian Integers": [[5, "building-the-gaussian-integers"]], "Calculating": [[1, "calculating"]], "Compactness": [[9, "compactness"], [9, "id5"]], "Complete lattice structure and internal direct sums": [[8, "complete-lattice-structure-and-internal-direct-sums"]], "Completeness": [[9, "completeness"]], "Concrete groups": [[7, "concrete-groups"]], "Conjunction and Iff": [[2, "conjunction-and-iff"]], "Continuous linear maps": [[10, "continuous-linear-maps"]], "Convergence and continuity": [[9, "convergence-and-continuity"]], "Defining structures": [[5, "defining-structures"]], "Differentiability": [[10, "differentiability"]], "Differential Calculus": [[10, null]], "Differential Calculus in Normed Spaces": [[10, "differential-calculus-in-normed-spaces"]], "Dimension": [[8, "dimension"]], "Disjunction": [[2, "disjunction"]], "Elementary Differential Calculus": [[10, "elementary-differential-calculus"]], "Elementary Integration": [[11, "elementary-integration"]], "Elementary Number Theory": [[4, null]], "Endomorphisms": [[8, "endomorphisms"]], "Filters": [[9, "filters"]], "Functions": [[3, "functions"]], "Fundamentals": [[9, "fundamentals"]], "Getting Started": [[0, "getting-started"]], "Group actions": [[7, "group-actions"]], "Groups and Rings": [[7, null]], "Groups and their morphisms": [[7, "groups-and-their-morphisms"]], "Hierarchies": [[6, null]], "Ideals and quotients": [[7, "ideals-and-quotients"]], "Implication and the Universal Quantifier": [[2, "implication-and-the-universal-quantifier"]], "Index": [[12, null]], "Induction and Recursion": [[4, "induction-and-recursion"]], "Infinitely Many Primes": [[4, "infinitely-many-primes"]], "Integration": [[11, "integration"]], "Integration and Measure Theory": [[11, null]], "Introduction": [[0, null]], "Irrational Roots": [[4, "irrational-roots"]], "Linear algebra": [[8, null]], "Linear maps": [[8, "linear-maps"]], "Logic": [[2, null]], "Mathematics in Lean": [[13, null]], "Matrices": [[8, "matrices"]], "Matrices, bases and dimension": [[8, "matrices-bases-and-dimension"]], "Measure Theory": [[11, "measure-theory"]], "Metric spaces": [[9, "metric-spaces"]], "Monoids and Groups": [[7, "monoids-and-groups"]], "Monoids and their morphisms": [[7, "monoids-and-their-morphisms"]], "More examples using apply and rw": [[1, "more-examples-using-apply-and-rw"]], "Morphisms": [[6, "morphisms"]], "Negation": [[2, "negation"]], "Normed spaces": [[10, "id3"]], "Overview": [[0, "overview"]], "Proving Facts about Algebraic Structures": [[1, "proving-facts-about-algebraic-structures"]], "Proving Identities in Algebraic Structures": [[1, "proving-identities-in-algebraic-structures"]], "Pushing and pulling subspaces": [[8, "pushing-and-pulling-subspaces"]], "Quotient groups": [[7, "quotient-groups"]], "Quotient spaces": [[8, "quotient-spaces"]], "Rings": [[7, "rings"]], "Rings, their units, morphisms and subrings": [[7, "rings-their-units-morphisms-and-subrings"]], "Separation and countability": [[9, "separation-and-countability"]], "Sequences and Convergence": [[2, "sequences-and-convergence"]], "Sets": [[3, "sets"]], "Sets and Functions": [[3, null]], "Structures": [[5, null]], "Sub-objects": [[6, "sub-objects"]], "Subgroups": [[7, "subgroups"]], "Subspace spanned by a set": [[8, "subspace-spanned-by-a-set"]], "Subspaces": [[8, "subspaces"]], "Subspaces and quotients": [[8, "subspaces-and-quotients"]], "Sums and products of vector spaces": [[8, "sums-and-products-of-vector-spaces"]], "The Existential Quantifier": [[2, "the-existential-quantifier"]], "The Schr\u00f6der-Bernstein Theorem": [[3, "the-schroder-bernstein-theorem"]], "Topological spaces": [[9, "topological-spaces"]], "Topology": [[9, null]], "Uniformly continuous functions": [[9, "uniformly-continuous-functions"]], "Using Theorems and Lemmas": [[1, "using-theorems-and-lemmas"]], "Vector spaces": [[8, "vector-spaces"]], "Vector spaces and linear maps": [[8, "vector-spaces-and-linear-maps"]]}, "docnames": ["C01_Introduction", "C02_Basics", "C03_Logic", "C04_Sets_and_Functions", "C05_Elementary_Number_Theory", "C06_Structures", "C07_Hierarchies", "C08_Groups_and_Rings", "C09_Linear_Algebra", "C10_Topology", "C11_Differential_Calculus", "C12_Integration_and_Measure_Theory", "genindex", "index"], "envversion": {"sphinx": 64, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["C01_Introduction.rst", "C02_Basics.rst", "C03_Logic.rst", "C04_Sets_and_Functions.rst", "C05_Elementary_Number_Theory.rst", "C06_Structures.rst", "C07_Hierarchies.rst", "C08_Groups_and_Rings.rst", "C09_Linear_Algebra.rst", "C10_Topology.rst", "C11_Differential_Calculus.rst", "C12_Integration_and_Measure_Theory.rst", "genindex.rst", "index.rst"], "indexentries": {"abel": [[1, "index-15", false], [7, "index-3", false]], "absolute value": [[1, "index-24", false]], "absurd": [[2, "index-17", false]], "anonymous constructor": [[2, "index-7", false]], "apply": [[1, "index-12", false], [1, "index-17", false]], "assumption": [[2, "index-19", false]], "bounded quantifiers": [[3, "index-3", false]], "by_cases": [[2, "index-23", false]], "by_contra": [[2, "index-14", false]], "by_contra and by_contradiction": [[2, "index-14", false]], "calc": [[1, "index-3", false]], "cases": [[2, "index-8", false]], "change": [[2, "index-2", false]], "check": [[0, "index-0", false]], "command": [[1, "index-9", false]], "commands": [[0, "index-0", false]], "commutative ring": [[1, "index-8", false]], "congr": [[2, "index-25", false]], "constructor": [[2, "index-18", false]], "continuity": [[9, "index-3", false]], "contradiction": [[2, "index-17", false]], "contrapose": [[2, "index-16", false]], "convert": [[2, "index-26", false]], "decide": [[4, "index-0", false]], "definitional equality": [[1, "index-13", false]], "differential calculus": [[10, "index-0", false]], "divisibility": [[1, "index-25", false]], "dsimp": [[2, "index-2", false]], "elementary calculus": [[10, "index-1", false]], "erw": [[2, "index-4", false]], "exact": [[1, "index-12", false], [1, "index-17", false], [1, "index-5", false]], "excluded middle": [[2, "index-22", false]], "exfalso": [[2, "index-17", false]], "exponential": [[1, "index-19", false]], "ext": [[2, "index-24", false]], "extensionality": [[2, "index-24", false]], "field_simp": [[2, "index-11", false]], "filter": [[9, "index-1", false]], "from": [[2, "index-12", false]], "gcd": [[1, "index-26", false]], "goal": [[1, "index-2", false]], "group": [[1, "index-15", false], [7, "index-2", false]], "group (algebraic structure)": [[1, "index-14", false], [7, "index-1", false]], "group (tactic)": [[1, "index-15", false], [7, "index-2", false]], "have": [[1, "index-11", false], [2, "index-12", false]], "implicit argument": [[1, "index-10", false]], "inequalities": [[1, "index-16", false]], "injective function": [[2, "index-5", false]], "integration": [[11, "index-0", false], [11, "index-1", false]], "intro": [[2, "index-0", false]], "lambda abstraction": [[2, "index-1", false]], "lattice": [[1, "index-28", false]], "lcm": [[1, "index-26", false]], "left": [[2, "index-21", false]], "let": [[2, "index-13", false]], "linarith": [[1, "index-18", false]], "linear map": [[8, "index-1", false]], "local context": [[1, "index-2", false]], "logarithm": [[1, "index-19", false]], "matrices": [[8, "index-3", false]], "max": [[1, "index-21", false]], "measure theory": [[11, "index-2", false]], "metric space": [[1, "index-30", false], [9, "index-2", false]], "min": [[1, "index-21", false]], "monoid": [[7, "index-0", false]], "monotone function": [[2, "index-3", false]], "namespace": [[1, "index-9", false]], "noncomm_ring": [[1, "index-15", false]], "norm_num": [[1, "index-20", false]], "normed space": [[10, "index-2", false]], "open": [[1, "index-9", false]], "order relation": [[1, "index-27", false]], "partial order": [[1, "index-27", false]], "proof state": [[1, "index-2", false]], "push_neg": [[2, "index-15", false]], "rcases": [[2, "index-9", false]], "real numbers": [[1, "index-1", false]], "refl and reflexivity": [[1, "index-13", false]], "reflexivity": [[1, "index-13", false]], "repeat": [[1, "index-23", false]], "rewrite": [[1, "index-0", false]], "rfl": [[1, "index-13", false]], "right": [[2, "index-21", false]], "ring": [[1, "index-6", false]], "ring (algebraic structure)": [[1, "index-7", false], [7, "index-4", false]], "ring (tactic)": [[1, "index-6", false]], "rintro": [[2, "index-9", false]], "rw": [[1, "index-0", false], [1, "index-4", false]], "rw and rewrite": [[1, "index-0", false], [1, "index-4", false]], "rwa": [[3, "index-2", false]], "set operations": [[3, "index-0", false]], "show": [[1, "index-22", false]], "simp": [[2, "index-20", false], [3, "index-1", false]], "surjective function": [[2, "index-10", false]], "tactics": [[1, "index-0", false], [1, "index-11", false], [1, "index-12", false], [1, "index-13", false], [1, "index-15", false], [1, "index-17", false], [1, "index-18", false], [1, "index-20", false], [1, "index-22", false], [1, "index-23", false], [1, "index-29", false], [1, "index-3", false], [1, "index-4", false], [1, "index-5", false], [1, "index-6", false], [2, "index-0", false], [2, "index-11", false], [2, "index-12", false], [2, "index-13", false], [2, "index-14", false], [2, "index-15", false], [2, "index-16", false], [2, "index-17", false], [2, "index-18", false], [2, "index-19", false], [2, "index-2", false], [2, "index-20", false], [2, "index-21", false], [2, "index-23", false], [2, "index-24", false], [2, "index-25", false], [2, "index-26", false], [2, "index-4", false], [2, "index-6", false], [2, "index-8", false], [2, "index-9", false], [3, "index-1", false], [3, "index-2", false], [4, "index-0", false], [7, "index-2", false], [7, "index-3", false], [9, "index-3", false]], "this": [[2, "index-12", false]], "topological space": [[9, "index-4", false]], "topology": [[9, "index-0", false]], "trans": [[1, "index-29", false]], "use": [[2, "index-6", false]], "vector space": [[8, "index-0", false]], "vector subspace": [[8, "index-2", false]]}, "objects": {}, "objnames": {}, "objtypes": {}, "terms": {"": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "0": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "02463336v2": 6, "1": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "10": [2, 8, 9], "11": [8, 10], "12": [4, 8], "13": 8, "15": 2, "16": 8, "17": 4, "2": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "263": 6, "27": 4, "29": 8, "2c": 4, "3": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "36": 8, "37": 2, "4": [0, 1, 2, 4, 5, 7, 8, 9, 10], "4c": 4, "5": [1, 2, 5, 7, 8, 9, 10], "50": 6, "512": 9, "6": [2, 4, 5, 6, 7, 8, 9, 10], "64": 9, "7": [2, 4, 5, 7, 8], "70": 6, "73": 6, "8": [2, 4, 7, 8, 9], "9": 8, "A": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "And": [2, 4, 6, 9], "As": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "At": [0, 1, 2, 4, 5, 6, 8], "Be": [1, 3], "But": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "By": [1, 3, 5, 6, 7, 8], "For": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "If": [0, 1, 2, 3, 4, 5, 6, 8, 9], "In": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "It": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "Its": [5, 6], "Not": [1, 5, 9], "Of": [1, 2, 4, 6, 7, 8, 9, 10, 11], "On": [1, 2, 3, 5, 6, 8, 9, 11], "One": [1, 2, 3, 4, 5, 6, 7, 8, 9], "Or": [2, 3, 8], "Such": [0, 1, 2, 6], "That": [0, 4, 5, 6], "The": [0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 13], "Their": [9, 10], "Then": [2, 3, 5, 6, 7, 8, 9, 11], "There": [0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11], "These": [0, 1, 3, 4, 5, 7, 10, 11], "To": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "With": [1, 3, 4, 6, 9], "_": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "_add_mod": 5, "_def": 4, "_eq": 5, "_in": 9, "_inst_1": 5, "_le": 5, "_n": 7, "_root_": [1, 3, 4], "a_0": 3, "a_1": 3, "a_2": 3, "a_def": 3, "a_of_b_of_c": 1, "ab": [0, 2, 5, 7], "abandon": 4, "abbrevi": [1, 2, 3, 5, 8], "abel": [1, 7], "abelian": [1, 5, 6, 8], "abgrpmodul": 6, "abil": 0, "abl": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10], "abn": 2, "about": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 13], "abov": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "abs_add": [1, 2], "abs_l": [1, 5], "abs_lt": 2, "abs_mod": 5, "abs_mul": 2, "abs_nonneg": 2, "abs_of_neg": 2, "abs_of_nonneg": [2, 5], "abs_po": 2, "abs_zero": 2, "absa": 2, "absb": 2, "absolut": 2, "absorb": 7, "absorb1": 1, "absorb2": 1, "absorpt": 1, "abstract": [1, 2, 5, 6, 7, 8, 9], "abstractli": 9, "absurd": [2, 4], "abus": 5, "ac": 5, "accept": [0, 1, 2, 8, 9], "access": [1, 3, 5, 6, 7, 8, 9, 11], "accessor": 5, "accid": 8, "accommod": [5, 7], "accompani": 5, "accord": [5, 8], "account": 8, "achiev": [5, 6, 9], "acknowledg": 0, "acpo": 2, "across": 6, "act": [1, 7, 8], "action": 8, "activ": 0, "actual": [2, 3, 4, 6, 7, 8, 9], "ad": [1, 2, 3, 4, 5, 6, 8, 9], "adapt": 5, "add": [2, 4, 5, 6, 7, 8, 9, 10], "add_assoc": [1, 4, 5, 6], "add_assoc\u2083": 6, "add_comm": [1, 4, 5, 6, 7], "add_def": 5, "add_im": 5, "add_l": 1, "add_le_add": [1, 2], "add_le_add_left": 1, "add_le_add_right": 1, "add_left_cancel": 1, "add_left_inj": 2, "add_lt_add_left": 1, "add_lt_add_of_le_of_lt": 1, "add_lt_add_of_lt_of_l": 1, "add_lt_add_right": 1, "add_mem": [7, 8], "add_mem_sup": 8, "add_mul": [1, 6], "add_mul_mod_self_left": 4, "add_neg_cancel_right": 1, "add_nonneg": [1, 5], "add_one_le_of_lt": 5, "add_po": 1, "add_pos_of_pos_of_nonneg": 1, "add_r": 5, "add_right_cancel": 1, "add_right_neg": 1, "add_smul": [6, 7, 8], "add_sub": 1, "add_sub_cancel": 4, "add_sub_cancel_right": 1, "add_vadd": 7, "add_x": 5, "add_zero": [1, 5, 6], "addact": 7, "addalt": 5, "addalt_comm": 5, "addalt_x": 5, "addcommgroup": [1, 7, 8], "addcommgroup\u2083": 6, "addcommmonoid": [7, 8], "addcommmonoid\u2083": 6, "addcommsemigroup\u2083": 6, "addequiv": 7, "addgroup": [1, 5, 7], "addgrouppoint": 5, "addgroup\u2081": 5, "addgroup\u2082": 5, "addgroup\u2083": 6, "addit": [1, 2, 4, 5, 6, 7, 8, 9, 10, 11], "addmonoid": [6, 7], "addmonoidhom": 7, "addmonoidhom\u2081": 6, "addmonoid\u2083": 6, "addmonoid\u2084": 6, "addsemigroup\u2083": 6, "addsubgroup": 7, "addzeroclass": 6, "adi": 5, "adjac": 8, "adject": 6, "adjug": 8, "adopt": 1, "advanc": 8, "advantag": [2, 3, 4, 5, 7, 10], "ae": [9, 11], "aestronglymeasur": 11, "aeval": [7, 8], "aeval_self_charpoli": 8, "aeval_x": 8, "affect": 6, "affin": 7, "aforement": 9, "after": [1, 2, 4, 6, 8, 9, 10], "again": [1, 2, 3, 4, 5, 6, 7, 8, 9], "against": 2, "agre": 3, "aid": 8, "aim": [4, 7], "aka": [8, 9], "aleb": 2, "alembert": 7, "alex": 0, "alexandru": 0, "algebra": [4, 6, 9, 10, 11, 13], "algebrahom": 6, "algebramap": 7, "alghom": 7, "algorithm": 5, "alistair": 0, "all": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "allow": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "almost": [5, 6, 7, 8, 9, 11], "alon": 3, "along": [1, 4, 7, 9], "alpha": [2, 3], "alreadi": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "also": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "altern": [0, 1, 2, 3, 4, 5, 6, 9], "although": [0, 3, 4, 5, 6, 7, 8, 9], "alwai": [0, 1, 2, 3, 5, 6, 7, 8], "ambient": 7, "ambigu": [1, 5], "among": 4, "amount": [7, 8], "an": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "analog": [1, 2, 3, 4, 8, 9], "analogi": [2, 5, 9, 10], "analysi": [0, 5, 8, 10], "ancient": 4, "and_comm": 3, "anecdot": 6, "angl": 2, "ani": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "ann": 5, "annoi": [4, 6], "annot": [1, 2, 3, 4, 5, 6], "announc": 8, "anonym": [2, 3, 4, 5, 7], "anoth": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "answer": [0, 5, 9], "antisymm": 3, "antisymmetr": [1, 2], "anyhow": 2, "anyth": [2, 5, 9], "anywai": [4, 7], "apart": [5, 6], "api": 1, "appeal": [3, 6], "appear": [0, 1, 2, 5, 6, 7, 8, 9], "appli": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13], "applic": [1, 2, 5, 7, 11], "apply_fun": 7, "appreci": 4, "approach": [4, 5, 6, 9], "appropri": [1, 2, 3, 5, 6], "approxim": 1, "ar": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "arbitrari": [1, 2, 3, 4, 5, 7, 8], "arbitrarili": [2, 9], "archetyp": [5, 8], "argu": 6, "argument": [1, 2, 3, 4, 5, 6, 7, 8, 9], "aris": 2, "arithmet": 1, "aroot": 7, "aroots_def": 7, "around": [1, 3, 6, 7, 8, 9, 11], "arrai": 8, "arrang": 5, "arrow": [1, 2, 6, 9], "artifici": [5, 8], "ascii": 6, "ascript": [6, 7, 8], "asid": 3, "ask": [2, 4, 5, 6, 7, 9], "aspect": [0, 5, 7], "assembl": [8, 9], "assert": [2, 3, 6, 7], "assign": [2, 3, 5, 6, 7], "assist": [0, 2, 5], "associ": [0, 1, 2, 4, 5, 6, 7, 8, 9, 11], "assum": [0, 1, 2, 3, 4, 6, 7, 8, 9], "assumpt": [0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11], "assur": 5, "asymmetri": 2, "attach": [8, 9], "attain": 9, "attempt": 6, "attent": [1, 2, 4, 6, 7, 9], "attop": [9, 11], "attop_basi": 9, "attr": 6, "attract": 2, "attribut": 6, "auto": [1, 6], "autom": [0, 1, 5], "automat": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "aux": [1, 2, 4, 9], "aux_card_eq": 7, "auxiliari": [2, 9], "avail": [0, 1, 2, 4, 5, 6, 7, 8], "averag": 5, "avoid": [1, 2, 3, 4, 5, 6, 7, 10], "awai": [2, 5], "awkward": 8, "axiom": [1, 2, 3, 5, 6, 7, 8, 9, 11], "axiomat": [1, 2, 3, 5], "az": 8, "b": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "b_indep": 8, "b_span": 8, "baanen": 5, "back": [0, 1, 2, 5, 6, 7, 8, 9], "background": [0, 7], "backslash": [1, 3], "backward": [2, 9], "bad": [5, 6, 8, 9], "badinst": 6, "bair": [9, 10], "balanc": 1, "ball": [3, 10], "banach": [10, 11], "bar": [0, 1, 2, 8], "bare": [6, 8], "barrier": 6, "bartosz": 0, "base": [0, 2, 3, 4, 6, 7, 9, 10, 13], "basi": [5, 8, 9], "basic": [0, 2, 4, 5, 8, 9, 11, 13], "basisfun": 8, "basissingleon": 8, "baz": 1, "bbb": [2, 5], "bc": 5, "bci": 5, "bd": 5, "becaus": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "becom": [1, 4, 5, 6, 9], "been": [0, 1, 2, 4, 5, 6, 8, 10], "befor": [0, 1, 2, 3, 4, 5, 6, 7, 8], "begin": [1, 2, 3, 4, 5, 6], "begun": 9, "behav": [2, 3, 6, 8, 9], "behavior": [3, 6, 9], "behind": [3, 7], "being": [1, 3, 5, 7, 8, 9, 10], "belong": [5, 6, 9], "below": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "benefit": [7, 8], "benjamin": 0, "beq": 2, "berman": 0, "bernardo": 0, "bernstein": 13, "besid": 6, "bespok": 5, "best": 0, "beta": [2, 3], "better": [3, 4, 5, 6, 9], "between": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "bewar": [1, 6, 8], "bex": 3, "bex_def": 3, "beyond": [2, 6, 10], "bhavik": 0, "bi": [1, 2, 5], "big": [0, 5, 7, 8, 9, 10], "bigcup_": 3, "bigger": [0, 3, 10], "bigoper": [4, 5, 7], "biject": [3, 5, 7, 8], "bijective_iff_injective_and_card": 7, "bilinear": 11, "binari": [1, 2, 4, 5, 6, 8], "binary_product": 8, "bind": [1, 3], "binder": 6, "bipartit": 5, "bit": [1, 2, 4, 6, 7, 8, 9], "black": [4, 6], "block": [1, 4, 7], "blur": 9, "bochner": 11, "bodi": 7, "boil": 6, "bold": 2, "bolt": 1, "book": [0, 2, 8, 9], "boolean": 1, "border": 9, "borelspac": 11, "boss": 9, "both": [1, 2, 3, 4, 5, 6, 7, 9, 10], "bother": [1, 3], "bottom": [6, 7, 8, 9], "bound": [1, 2, 3, 4, 5, 8, 9, 10, 11], "bounded": 10, "bounded_of_ex_finset": 4, "bourbaki": 9, "box": 4, "bpo": [2, 9], "bq": 5, "brace": [1, 8], "bracket": [1, 2, 5, 6, 7], "branch": [2, 3, 6], "break": 6, "breviti": [1, 5], "briefli": 7, "bring": [3, 4, 9], "broader": [4, 10], "broadest": 5, "brown": 0, "brows": [0, 1, 4, 7], "bryan": 0, "build": [0, 2, 4, 6, 7, 8, 9, 13], "builder": 3, "built": [0, 2, 6, 7, 8], "builtin": 6, "bulb": 5, "bulwi": 0, "bundl": [5, 6, 7, 8, 9, 10], "button": 0, "by_cas": [2, 3, 4], "by_contra": [2, 4], "c": [0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11], "c_mul": 7, "c_neg": 7, "cach": 0, "calc": [1, 2, 3, 5, 7, 9], "calcul": [0, 2, 4, 5, 13], "calculu": [9, 11, 13], "call": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "can": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "candid": 5, "cannot": [2, 3, 4, 5, 6, 7, 8, 9], "canon": [2, 3, 4, 5, 8], "cantor": 3, "cap": 3, "capabl": 5, "capit": 5, "captur": 8, "card": 7, "card_congr": 7, "card_dvd_of_l": 7, "card_eq_one_iff_exist": 7, "card_po": 7, "card_sigma": 7, "cardin": [3, 7, 8], "care": [1, 2, 3, 5, 8], "carneiro": 0, "carri": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "carrier": [1, 5, 6, 7, 8], "case": [1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "categor": 9, "categori": [5, 8, 9, 10], "cauchi": 9, "cauchyseq": 9, "cauchyseq_iff": 9, "cauchyseq_of_le_geometric_two": 9, "cauchyseq_tendsto_of_complet": 9, "caveat": 7, "caylei": [7, 8], "cayleyisomorph": 7, "cdist": 9, "cdot": 5, "center": [0, 9], "central": [0, 4], "centuri": 3, "ceq": 2, "certain": [2, 6, 9], "certifi": 0, "cha": 0, "chain": 5, "challeng": [0, 1, 2, 3, 5, 10], "chanc": 2, "chang": [0, 1, 2, 4, 5, 9, 11], "chapter": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "char": 0, "charact": [1, 3, 6], "character": [1, 3, 4, 8, 9, 10], "characterist": 8, "charpoli": 8, "chat": 0, "cheat": [0, 1], "check": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "checksynthord": 6, "chen": 0, "chestnut": 2, "chines": 7, "chineseiso": 7, "chinesemap": 7, "chinesemap_inj": 7, "chinesemap_mk": 7, "chinesemap_surj": 7, "choic": [1, 2, 3, 5, 8, 9], "choos": [0, 2, 3, 4, 5, 6, 7, 9], "choose_spec": 3, "chose": 6, "chosen": [2, 5], "circ": [3, 5], "circl": 7, "circleequ": 7, "claim": 9, "clarifi": 5, "clash": 1, "class": [1, 4, 5, 6, 7, 8, 9, 10, 11], "classic": [2, 3, 4, 7, 8], "claus": 6, "clean": [2, 9], "clear": [1, 2, 4, 5, 6], "clearer": [1, 3, 5], "clearli": 9, "clever": 1, "click": [0, 1, 3, 4, 5, 6], "clock": 0, "clontz": 0, "close": [1, 2, 3, 6, 7, 8, 10, 11], "closed_nhds_basi": 9, "closedbal": 9, "closer": [2, 9], "closur": [7, 8, 9], "closure_iscycl": 7, "cloud": 0, "clue": 7, "clunki": 9, "cluster": 9, "clusterpt": 9, "cmd": [1, 2], "co": [2, 7], "cocki": 1, "code": [0, 1, 2, 3, 5, 6, 8], "codomain": [2, 4, 9], "coe": 6, "coe_inject": 6, "coe_natabs_norm": 5, "coeff": 7, "coeffici": [5, 7, 8], "coefun": 6, "coelinearmap": 8, "coerc": [6, 7, 8], "coercion": [5, 6, 7, 8, 9, 10], "coincid": [4, 5, 9], "coinduc": 9, "coinduced_compos": 9, "coinduced_le_iff_le_induc": 9, "col": 8, "collari": 0, "collect": [1, 2, 3, 5, 8, 9, 11], "collis": 6, "colon": [2, 8], "column": 8, "comap": [7, 8, 9], "comap_bot": 8, "comap_comap": 9, "comap_map_eq": 8, "comapmkqreliso": 8, "combin": [1, 2, 5, 6, 7, 8, 9], "come": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "comfort": 0, "comm": 7, "comma": [1, 8], "command": [0, 1, 2, 3, 4, 5, 6, 7, 8], "commelin": 0, "comment": [0, 4], "commgroup": 1, "commgroup\u2083": 6, "commmonoid": 6, "commmonoid\u2083": 6, "common": [1, 2, 3, 4, 5, 7, 8, 9], "commonli": [4, 5], "commr": [1, 2, 5, 7], "commsemigroup\u2083": 6, "commsemir": [7, 8], "commun": [0, 4], "commut": [1, 2, 3, 4, 5, 6, 7, 8, 10], "comp": [7, 8, 9], "comp_id": 8, "compact": 11, "compactspac": 9, "compani": 2, "companion": [0, 1], "compar": [0, 5, 6, 8, 9], "comparison": 6, "compat": [1, 7, 9], "compat_mymap": 7, "compl": 11, "complain": 1, "complement": [3, 8, 9, 11], "complementari": 0, "complet": [0, 1, 2, 3, 4, 6, 7, 10], "completespac": [9, 10, 11], "complex": [0, 1, 2, 4, 5, 7, 8, 10, 11], "complic": [1, 2, 6, 7, 8], "compon": [2, 3, 5, 8, 9, 11], "compos": [3, 5, 7, 9], "composit": [2, 3, 5, 6, 7, 8, 9], "compound": [1, 2, 9], "compress": [0, 1, 9], "comput": [0, 2, 3, 4, 5, 7, 8, 10, 11], "computation": [4, 8], "concentr": 3, "concept": [5, 7, 8, 9, 10], "conceptu": [3, 7], "concis": [1, 5, 7], "conclud": [2, 10], "conclus": [1, 2, 4], "concret": [1, 2, 4, 5, 6, 8, 9], "condens": 3, "condit": [3, 4, 6, 7, 8, 9, 10], "confid": 3, "configur": 5, "confirm": [1, 2, 3, 4], "confus": [3, 4, 6, 7, 9], "congr": 2, "congratul": [1, 2, 4], "congruent": 4, "conj": 5, "conj_im": 5, "conj_r": 5, "conjug": [5, 7], "conjugate_on": 7, "conjunct": [1, 6, 13], "connect": [1, 3, 5, 8, 9], "consequ": 7, "consid": [1, 2, 3, 4, 5, 6, 7, 9, 10, 11], "consider": 8, "consist": [1, 3, 5, 6, 7, 8, 9, 10], "constant": [1, 2, 7, 11], "constantli": 7, "constitut": 1, "constr": 8, "constr_basi": 8, "constraint": [5, 9], "construct": [0, 2, 3, 4, 5, 6, 7, 8, 9], "constructor": [1, 2, 3, 4, 5, 6], "consult": 5, "cont": 10, "contain": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "contdiff": 10, "contdiff_iff_continuous_differenti": 10, "contdiffat": 10, "contend": 4, "content": [0, 1, 2, 4, 9], "context": [1, 2, 4, 5, 6, 7, 8, 9, 10, 11], "contextu": 5, "continu": [0, 1, 4, 5, 6, 8, 11], "continuous_def": 9, "continuous_dist": 9, "continuous_fst": 9, "continuous_id": [6, 9], "continuous_iff": 9, "continuous_iff_coinduced_l": 9, "continuous_linear_map": 10, "continuous_pow": 9, "continuous_snd": 9, "continuousat": [9, 11], "continuousat_extend": 9, "continuousat_iff": 9, "continuouslinearmap": 10, "continuouson": [9, 10], "continuum": 2, "contort": 7, "contract": 2, "contradict": [2, 3, 4], "contradictori": 2, "contrapos": [2, 3, 4], "contrari": 2, "contrast": [2, 3, 5, 6, 9], "contravari": 9, "contribut": [0, 3], "contributor": 8, "control": 2, "conveni": [1, 2, 3, 5, 6, 7, 8, 9], "convent": [1, 5, 7, 11], "convention": 9, "converg": [11, 13], "convergesto": 2, "convergesto_add": 2, "convergesto_const": 2, "convergesto_mul": 2, "convergesto_mul_const": 2, "convergesto_uniqu": 2, "convers": [0, 2, 4, 7, 8, 9], "convert": [2, 4, 7, 8], "convinc": 5, "convolut": 11, "coordin": [7, 8], "copi": [0, 3, 4, 6, 7, 8, 9], "coprim": [4, 7], "coprime_mn": 4, "coprod": 8, "coprod_inl": 8, "coprod_inr": 8, "coproduct": 8, "core": [0, 4, 5], "corner": 7, "corollari": 7, "correct": [0, 1, 7], "correctli": 3, "correspond": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "could": [0, 1, 2, 4, 5, 6, 7, 8, 9], "count": 7, "count_factors_mul_of_po": 4, "countabl": 11, "counter": 8, "counterexampl": [2, 10], "counterpart": 5, "coupl": [1, 2, 6, 8, 9], "cours": [1, 2, 4, 6, 7, 8, 9, 10, 11], "covari": 9, "cover": [0, 1, 3, 6, 7, 8, 9, 10], "cramer": 8, "creat": [0, 1, 4, 6], "creation": 7, "creativ": 5, "criterion": 9, "crucial": [7, 8, 9], "crude": 4, "cryptic": 2, "ct": 2, "ctrl": [0, 1, 2, 4, 5], "cube": 7, "cue": 5, "cup": 3, "curiou": [1, 6], "curli": [1, 2, 8], "current": [1, 2, 5, 6], "curri": 1, "cursor": [0, 1, 2], "curv": 0, "custom": 5, "cut": 4, "cycl": 7, "cyclic": 7, "czubin": 0, "d": [1, 2, 4, 5, 7, 8, 10], "dai": 3, "danger": [4, 5], "data": [1, 2, 4, 5, 6, 8, 9], "databas": [3, 4, 6, 9], "datatyp": 4, "de": 0, "deal": [1, 2, 3, 4, 5, 8, 9], "dealt": 2, "decid": [4, 7, 8, 9], "decidableeq": [4, 8], "decidablepr": 4, "decis": [4, 7], "declar": [0, 1, 4, 5, 6, 7, 8], "decompos": [0, 3], "decreas": [1, 5], "dedekind": 3, "deduc": [6, 7, 9], "def": [0, 2, 3, 4, 5, 6, 7, 8, 9], "default": [1, 2, 3, 4, 5, 6, 7, 10], "defect": [2, 6, 9], "defin": [1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 13], "definit": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "definition": [1, 4, 5, 6, 9], "degre": 7, "degree_mul": 7, "delet": [1, 2, 3], "delic": 3, "delimit": 1, "demonstr": [6, 9], "deni": 0, "denomin": [2, 4, 5], "denot": [1, 3, 4, 6, 7, 8, 9], "dens": 9, "denseinduc": 9, "densiti": 9, "depend": [0, 2, 3, 4, 5, 6, 7, 8, 9], "deriv": [1, 2, 4, 7, 10, 11], "deriv_add": 10, "deriv_eq_zero": 10, "deriv_zero_of_not_differentiableat": 10, "descend": [6, 7], "describ": [0, 1, 2, 3, 4, 5, 6, 8, 9], "descript": [0, 1, 2, 4, 9], "deserv": 4, "design": [0, 1, 2, 3, 5, 7, 8, 9], "desir": [1, 3, 6, 7, 9], "despit": 8, "destruct": 2, "destructur": 6, "det": [8, 11], "det_mul": 8, "det_on": 8, "detail": [1, 2, 3, 4, 5, 6, 7], "detect": 2, "determin": [1, 5, 7, 8, 9], "develop": [0, 1, 4, 7, 11], "devic": 6, "devot": 9, "dfun": 6, "dfunlik": 6, "di": [2, 5], "dia": 6, "dia_assoc": 6, "dia_inv": 6, "dia_on": 6, "diagram": 3, "diamond": 6, "diaoneclass\u2081": 6, "dia\u2081": 6, "dictionari": 1, "did": [0, 2, 6, 9], "dif_neg": 3, "dif_po": 3, "diff_eq": 3, "differ": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "differenti": [11, 13], "differentiableat": 10, "differentiableon": 10, "difficult": [2, 6], "digress": 9, "dimens": 13, "dimension": [8, 10, 11], "direct": [1, 2, 3, 6, 7, 9, 10], "directli": [1, 2, 4, 5, 6, 8, 9], "directsum": 8, "discret": 5, "discuss": [1, 2, 4, 5, 6, 7, 8, 9, 10], "dishwash": 0, "disjoint": [3, 7, 11], "disjunct": [1, 3, 13], "dispens": 4, "displai": [0, 1, 2, 6], "dispos": 2, "dist": [1, 9], "dist_comm": [1, 9], "dist_eq_zero": 9, "dist_le_range_sum_dist": 9, "dist_nonneg": [1, 9], "dist_self": 1, "dist_triangl": [1, 9], "distanc": [1, 2, 9, 10], "distinct": [0, 2, 3, 4, 5, 8, 9], "distinguish": [0, 5, 6, 7, 9, 10], "distract": 6, "distriblattic": 1, "distribut": [1, 4, 5, 6], "div": 5, "div_def": 5, "div_dvd_of_dvd": 4, "div_eq_mul_inv": 5, "div_eq_of_eq_mul_right": 4, "div_lt_self": 4, "div_nonneg": 5, "div_po": 2, "divab": 2, "divac": 2, "divbc": 2, "dive": 0, "divid": [1, 2, 4, 5, 7], "divis": [1, 2, 4, 5, 6, 8], "divisor": [1, 2, 4, 5, 7], "do": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "doc": 0, "document": [0, 1, 3, 4, 6], "doe": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "doesn": [1, 2, 7, 8, 9], "domain": [1, 2, 3, 4, 5, 7, 9], "domin": 11, "don": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "done": [0, 2, 3, 4, 6, 7, 8, 9], "doorn": 0, "dot": [1, 7, 8, 9], "doubl": [2, 3], "doubli": 7, "doubt": 0, "down": [0, 3, 4, 6, 9], "downsid": [7, 8], "dozen": 3, "draw": [1, 5, 6], "drop": 2, "dsimp": [2, 3, 5, 7, 8], "dual": [5, 9], "dualli": 9, "duca": 0, "due": [1, 6], "duplic": 6, "dvd": 1, "dvd_add_iff_left": 4, "dvd_antisymm": 1, "dvd_fac": 4, "dvd_factori": 4, "dvd_gcd": 4, "dvd_gcd_iff": 2, "dvd_iff_exists_eq_mul_left": 4, "dvd_mul": 4, "dvd_mul_left": 1, "dvd_mul_of_dvd_left": 1, "dvd_mul_of_dvd_right": 4, "dvd_mul_right": [2, 4], "dvd_of_dvd_pow": 4, "dvd_prod_of_mem": 4, "dvd_sub": 4, "dvd_tran": 1, "dwell": 3, "e": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "each": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "earli": 8, "earlier": [1, 7, 8], "easi": [0, 4, 5, 6, 7, 8, 9], "easier": [0, 1, 3, 4, 6, 9], "easiest": [2, 4], "easili": [1, 4, 5, 6, 7, 8], "ebner": 0, "eccentr": 8, "edit": 0, "editor": [0, 1], "ediv_add_emod": 5, "ediv_lt_of_lt_mul": 5, "ediv_mul_l": 5, "ef": 2, "effect": [1, 3, 6, 9], "effici": [5, 7, 8, 9], "effort": [1, 4], "eg": 2, "eigenspac": 8, "eigenspace_def": 8, "eigenvalu": 8, "eigenvector": 8, "eight": 9, "either": [1, 2, 3, 5, 6, 9], "elabor": [8, 9], "ele1": 2, "eleg": 5, "element": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "elementari": [0, 3, 5, 7, 8, 9, 13], "elim": 2, "elim_finite_subcov": 9, "elimin": 1, "els": [2, 3, 4, 8], "em": [2, 3], "emanuel": 0, "emb": 5, "embark": 6, "embed": 7, "embodi": 7, "emetricspac": 9, "emod_lt": 5, "emod_lt_of_po": 5, "emod_nonneg": 5, "emphas": [6, 7], "emphasi": [0, 6], "empti": [3, 4, 5, 7, 9, 11], "enabl": [2, 3, 4, 5], "enat": 4, "encapsul": [3, 5, 10], "encod": [7, 11], "encount": [4, 6], "encourag": [0, 1, 2, 3, 4, 5], "end": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "endomorph": [7, 13], "endow": [6, 7, 8], "enforc": 7, "engin": 4, "enjoi": [2, 3, 4, 9], "ennreal": 11, "enough": [0, 1, 2, 3, 4, 6, 7, 8, 9], "ensur": [6, 7, 8, 9], "enter": [0, 1, 2, 3, 7, 9], "enthusiast": 0, "entir": [1, 3, 5, 9, 10], "entourag": 9, "entri": [0, 5, 7, 8], "enumer": [1, 2], "epo": 2, "eq": 5, "eq1": 4, "eq2": 4, "eq_bot": 8, "eq_bot_iff": 8, "eq_bot_iff_card": 7, "eq_bot_iff_foral": 7, "eq_empty_or_nonempti": 9, "eq_neg_of_add_eq_zero": 1, "eq_of_dvd_of_prim": 4, "eq_of_mul_eq_mul_right": 7, "eq_one_or_self_of_dvd": 4, "eq_top_iff": 7, "eq_two_or_odd": 3, "eq_univ": 3, "eq_univ_of_foral": 3, "eq_zero_iff_mem": 7, "eq_zero_or_eq_zero_of_mul_eq_zero": 2, "equal": [1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "equat": [1, 2, 3, 4, 5], "equilater": 5, "equip": [1, 3, 5, 6, 7, 9, 10, 11], "equiv": [5, 7, 8], "equival": [1, 2, 3, 4, 5, 7, 8, 9, 10, 11], "eras": 4, "eric": 0, "error": [1, 2, 3, 6], "erw": 2, "especi": [1, 2, 5, 6, 7, 8, 9], "essenti": [2, 3, 5, 7, 9], "establish": [0, 1, 2, 3, 4, 5], "eta": 5, "etc": [8, 9], "euclidean": 5, "euclideandomain": 5, "eval": [0, 7, 8], "evalu": [7, 8], "eval\u2082": 7, "even": [0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11], "even_of_even_sqr": 4, "eventu": [2, 3, 9], "eventually_eventually_nhd": 9, "eventually_left_invers": 10, "eventually_right_invers": 10, "eventuallyeq": 9, "ever": [0, 9], "everi": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "everyth": [1, 2, 6, 9], "everywher": [2, 3, 6, 8, 9, 11], "evid": 5, "evolv": 1, "ex": [0, 2], "ex_finset_of_bound": 4, "exact": [1, 2, 3, 4, 5, 7, 8, 9], "exactli": [1, 2, 3, 5, 6, 7, 9], "exampl": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13], "except": [1, 2, 5, 7], "exclam": 9, "exclud": [2, 4], "exercis": [0, 1, 2, 3, 5, 6, 7, 8, 9, 10], "exfalso": 2, "exhibit": [2, 9], "exist": [1, 2, 3, 6, 7, 8, 9], "existenti": [3, 7, 13], "exists_abs_le_of_convergesto": 2, "exists_deriv_eq_slop": 10, "exists_deriv_eq_zero": 10, "exists_haseigenvector": 8, "exists_infinite_prim": 3, "exists_ismaxon": 9, "exists_isminon": 9, "exists_one_lt_norm": 10, "exists_prime_and_dvd": 3, "exists_prime_factor": 4, "exists_prime_factor_mod_4_eq_3": 4, "exists_subgroup_card_pow_prim": 7, "exot": [7, 9], "exp": [1, 3], "exp_le_exp": 1, "exp_log": 3, "exp_lt_exp": 1, "exp_po": [1, 3], "expand": [1, 2, 3, 4, 5, 6, 8], "expect": [1, 2, 3, 4, 5, 6, 7, 8, 9], "experi": [0, 1, 9], "explain": [1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "explan": [0, 7, 8, 9], "explicit": [1, 2, 5, 6, 8, 9], "explicitli": [1, 2, 3, 5, 6, 7, 8, 9, 10], "explor": [4, 8, 9], "expon": 1, "exponenti": 4, "export": 6, "expos": [2, 9], "express": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "ext": [2, 3, 4, 5, 6, 7, 8], "ext_iff": 5, "extend": [1, 3, 4, 5, 6, 9, 11], "extens": [0, 1, 6, 9, 10], "extension": [3, 5], "extern": 8, "extra": [1, 2, 3, 5, 6, 7, 9], "extract": [2, 9], "extrem": [0, 6, 9], "f": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "f_": 9, "f_cont": 9, "f_le": 9, "f_ne": 9, "fac": 4, "fac_po": 4, "face": [5, 6, 9], "facilit": [2, 8, 9], "fact": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13], "factor": [4, 5, 7, 8], "factori": 4, "factorial_po": 4, "factorization_mul": 4, "factorization_pow": 4, "fail": [1, 2, 4, 5, 6, 8, 9, 11], "failur": 6, "fairli": 2, "fals": [1, 2, 3, 4, 6], "falso": 2, "famili": [7, 8, 9, 10], "familiar": [0, 1, 4, 5, 8, 9, 10], "famou": [3, 7], "far": [2, 3, 6, 8, 9], "favor": [1, 5], "fderiv": 10, "fear": 6, "feat": 4, "featur": [0, 2, 4, 7], "feed": 7, "feedback": 0, "feel": [0, 1, 2, 6, 8, 9], "fermatlasttheorem": 0, "fetch": 0, "few": [1, 2, 3, 4, 9], "field": [0, 1, 5, 6, 7, 8, 10], "field_simp": [2, 5], "figur": [0, 1, 2, 5], "file": [0, 1, 4, 5, 6, 7, 9], "filippo": 0, "fill": [2, 3, 4, 5], "filter": [4, 10, 11, 13], "filter_upward": 9, "filteri": 9, "fin": [5, 7, 8, 11], "fin_cas": 8, "final": [1, 2, 3, 5, 7, 8, 9, 11], "finaliso": 7, "find": [0, 1, 2, 4, 5, 6, 8, 9], "fine": 8, "finicki": 1, "finish": [1, 2, 3, 4, 7], "finit": [1, 3, 4, 5, 7, 8, 9, 10, 11], "finitedimension": [8, 10, 11], "finrank": 8, "finrank_eq_rank": 8, "finrank_fin_fun": 8, "finrank_l": 8, "finrank_pos_iff": 8, "finrank_real_complex": 8, "finrank_self": 8, "finrank_sup_add_finrank_inf_eq": 8, "finset": [4, 5, 7, 8, 9], "finsupp": 8, "fintyp": [7, 8, 9], "fintypebasisindex": 8, "first": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "firstcountabletopologi": 9, "fix": [4, 6, 7, 8, 9], "flag": [2, 3], "flavor": 8, "flexibl": 9, "flori": 0, "fn_ub_add": 2, "fneven": 2, "fnhaslb": 2, "fnhasub": 2, "fnlb": 2, "fnodd": 2, "fnub": 2, "fnub_add": 2, "fnuba": 2, "focu": [0, 1, 7, 8, 9, 11], "focus": 9, "folder": 0, "follow": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "font": 7, "foo": [1, 5], "forc": [1, 2, 3, 7, 8], "foreshadow": 1, "forewarn": 0, "forget": 6, "form": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "formal": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "format": 1, "former": 5, "formul": [4, 7, 9], "formula": [7, 11], "forth": 5, "fortiori": 9, "fortun": 3, "forward": [1, 2, 5, 7, 9], "found": [1, 5, 7, 8, 10], "foundat": [2, 3, 4, 5, 7, 8], "four": [2, 5], "fourth": 2, "frac": 5, "fraction": 4, "fraenkel": 2, "framework": [0, 8], "frasa": 0, "free": [0, 1, 7, 8, 9], "freegroup": 7, "freeli": 4, "frequent": 9, "friend": [2, 5], "friendli": 7, "from": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "front": 2, "frustrat": [0, 6], "fr\u00e9chet": 10, "fst": [5, 8, 9], "fubini": 11, "full": [1, 2, 3, 4, 5, 6, 7, 8, 9], "fulli": [3, 7, 8, 9], "fun": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "function": [1, 2, 4, 5, 6, 7, 8, 10, 11, 13], "functori": 9, "fundament": [0, 4, 5, 6, 11], "funni": 9, "further": [1, 9], "furthermor": 7, "g": [1, 2, 3, 5, 6, 7, 8, 9, 10, 11], "g_": 9, "g_1": 5, "g_2": 5, "g_3": 5, "gabriel": 0, "gadget": [2, 9], "gain": 6, "galoi": [3, 5, 8, 9], "galoisinsert": 8, "game": [0, 6], "gauss": 7, "gaussian": [2, 7, 13], "gaussianint": 5, "gaussint": 5, "gave": [7, 9], "gcd": [1, 2, 4], "gcd_zero_left": 1, "gcd_zero_right": 1, "gcongr": 5, "ge": [0, 2, 5], "gener": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "genuin": 2, "geometr": 9, "geometri": 7, "get": [1, 2, 3, 4, 6, 7, 8, 9, 10, 13], "gi": 8, "gin": 0, "giovanni": 0, "git": 0, "github": [0, 1], "gitpod": 0, "give": [1, 2, 3, 4, 6, 7, 8, 9, 11], "given": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "glb": 1, "global": [7, 9], "go": [0, 1, 2, 3, 4, 6, 8, 9], "goal": [0, 1, 2, 3, 4, 5, 8, 9], "goe": [3, 4, 5, 6, 9], "good": [1, 2, 3, 4, 5, 6, 7, 8, 9], "gorbachev": 0, "got": 6, "govern": [1, 5], "gradual": [6, 9], "graph": [5, 8], "grate": [0, 5], "great": [1, 5], "greater": [0, 1, 2, 3, 4, 9], "greatest": [1, 5, 9], "greef": 0, "greek": [1, 4], "group": [0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 13], "groupact": 7, "groupcat": 5, "groupequivquotientprodsubgroup": 7, "grouptheori": 5, "group\u2081": [5, 6], "group\u2081cat": 5, "group\u2082": 5, "group\u2083": 6, "grow": [0, 6, 7], "grp": 5, "guai": 0, "guarante": [0, 3, 5, 8], "guess": [1, 2, 3, 4, 5, 8], "guilherm": 0, "gya": 3, "g\u2080": 7, "g\u2081": 7, "g\u2082": 7, "h": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "h0": 4, "h1": [1, 2, 3, 4, 5], "h2": [1, 2, 3, 5], "h3": 1, "h_def": 3, "h_inj": 11, "ha": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "hab": 10, "habit": [6, 8], "hac": 6, "hack": 3, "had": [1, 6, 8], "hal": 6, "half": [3, 7], "hamilton": 8, "hand": [1, 2, 3, 4, 5, 6, 8, 9], "handi": 4, "handl": [1, 3, 4, 6, 7], "hanson": 0, "happen": [1, 6, 9], "happi": 0, "hard": [0, 1, 3, 5, 6, 7], "harder": [2, 5, 8], "harm": 3, "hasbasi": 9, "hasderivat": [10, 11], "hasderivat_sin": 10, "haseigenvalu": 8, "haseigenvalue_iff_isroot": 8, "haseigenvalue_of_haseigenvector": 8, "haseigenvector": 8, "hasfderivat": 10, "hasfderivatfilt": 10, "hasfderivatfilter_iff_islittleo": 10, "hasfderivwithinat": [10, 11], "hasinvgroup\u2082": 5, "haskel": 1, "hasmulgroup\u2082": 5, "hasonegroup\u2082": 5, "hasquoti": 6, "hasstrictfderivat": 10, "hausdorff": 9, "have": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "haven": [0, 2, 6, 9], "hb": [2, 9], "hba": 6, "hball": 9, "hbound": 11, "hc": 10, "hd": 9, "hdi": 11, "hdvd": 7, "he": 7, "headach": 4, "headi": 5, "heart": [4, 7], "heather": 5, "heaven": 5, "heavier": 6, "heavili": 9, "hello": 0, "help": [0, 1, 2, 3, 4, 5, 6, 8, 9], "helper": 1, "henc": [0, 2, 3, 4, 5, 6, 8, 9, 10], "here": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "hesit": 4, "hf": [3, 7, 9, 10, 11], "hfa": 2, "hfc": 10, "hff": 10, "hfi": 10, "hfx": 9, "hg": [3, 9, 10, 11], "hgb": 2, "hi": 7, "hidden": 2, "hide": [6, 7, 9], "hierarchi": [5, 7, 8, 13], "high": [2, 7], "higher": 6, "highlight": [0, 2], "hij": 8, "hint": [0, 1, 2, 11], "histor": [1, 7], "hit": [0, 1], "hk": [0, 10], "hle": 9, "hlim": 11, "hm": 10, "hmea": 11, "hmn": 0, "hmp": 10, "hn": [3, 4, 9, 10], "hna": 2, "hnb": 2, "hne": 9, "ho": 9, "hold": [1, 2, 3, 4, 5, 7, 8, 9, 11], "home": [4, 5], "homomorph": 7, "hood": [3, 5, 8], "hope": [0, 1, 8], "hopelessli": 6, "hoskinson": 0, "hover": [0, 1, 2, 3, 4, 5], "how": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "howev": [1, 2, 5, 6, 7, 8, 9, 10], "hp": [7, 9], "hpo": 9, "hq": [7, 9], "hr": 9, "hst": 7, "hsu": 9, "ht": 2, "html": 0, "http": 6, "hu": [9, 10], "huge": 6, "huisinga": 0, "hum": 9, "human": 1, "hunt": [6, 8], "hunter": 0, "huo": 9, "hurdl": 6, "hurt": 2, "hux": 9, "hv": 8, "hw": 6, "hx": [2, 3, 5, 6, 7, 8, 10], "hxeq": 3, "hy": [5, 6, 7, 8], "hyp": 1, "hypothes": [1, 2, 3, 4, 5], "hypothesi": [0, 1, 2, 3, 4], "hz": [5, 6], "h\u03b5": 10, "h\u03c6": 8, "h\u2080": [1, 2, 3, 4, 9], "h\u2081": [1, 2, 3, 4], "h\u2082": [1, 3, 4], "h\u2083": [1, 3], "i": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "icc": [9, 10], "ici": 9, "id": [4, 6, 8, 9, 10], "id_comp": 8, "idea": [1, 2, 3, 5, 6, 8, 9], "ideal": 8, "ident": [3, 4, 5, 6, 7, 8, 9, 13], "identif": 8, "identifi": [1, 2, 4, 8], "if_neg": 3, "if_po": 3, "iff": [1, 3, 7, 8, 9, 10, 11, 13], "ignor": [0, 5, 7, 8, 9], "ih": 4, "iinf_insert": 7, "iinter": 11, "il": 4, "illustr": [1, 2, 3, 4, 5, 7], "im": 5, "imag": [3, 4, 6, 7, 8, 9], "image_subset_iff": 3, "imagin": 1, "imaginari": 5, "immedi": [2, 3, 5, 6, 8], "implement": [2, 5, 6, 7, 8, 10], "impli": [1, 2, 3, 4, 5, 8, 9], "implic": [1, 8, 9, 13], "implicit": [1, 2, 5, 6, 7, 8, 9, 10], "implicitli": [1, 2], "import": [1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "importantli": [6, 7, 8], "imposs": 1, "impress": 0, "improv": [3, 4], "incl": 9, "includ": [0, 1, 2, 3, 4, 6, 7, 8, 9, 10], "inclus": [1, 3, 7, 8, 9], "inconsist": [1, 8], "inconveni": 10, "incorpor": 6, "increas": 1, "increment": [0, 1], "inde": [1, 5, 6, 7, 8, 9, 10], "indefinit": 4, "indent": 1, "independ": [2, 3, 5, 8], "indetermin": 7, "index": [3, 6, 7, 8, 9], "index_eq_card": 7, "index_mul_card": 7, "indic": [1, 2, 3, 5, 6], "indirect": 6, "indirectli": 1, "individu": 1, "induc": 9, "induced_compos": 9, "induct": [7, 8, 9, 13], "induction_on": 4, "inequ": [1, 2, 6, 9], "inf": [1, 6, 9], "inf_assoc": 1, "inf_bot_of_coprim": 7, "inf_comm": [1, 7], "inf_eq_bot": 8, "inf_le_left": [1, 9], "inf_le_right": 1, "inf_sup_left": 1, "inf_sup_right": 1, "inf_sup_self": 1, "infer": [1, 2, 3, 5, 6, 7, 8], "infer_inst": [10, 11], "inferenti": 0, "inferinst": [7, 8], "inferr": 6, "infimum": [1, 6, 7, 8, 9, 11], "infin": [4, 9, 11], "infinit": [3, 8, 9, 13], "infix": [1, 6], "infixl": 6, "infixr": 6, "inform": [0, 1, 2, 3, 5, 6, 8, 9], "infoview": [1, 6], "infrastructur": 0, "infti": 10, "ingredi": [3, 5, 9, 10], "inhabit": [3, 5, 9], "inherit": [5, 6, 7, 8], "inherit_doc": 6, "inj": 4, "inject": [2, 3, 4, 6, 7, 8, 9], "injective_lift_iff": 7, "injf": [2, 3], "injg": 2, "injon": [3, 11], "inl": [2, 3, 8], "inner": 3, "input": [1, 3, 8, 9], "inr": [2, 3, 8], "inria": 6, "inscrut": [2, 3], "insert": [0, 2, 4, 5, 7, 8, 9, 10], "insid": [0, 1, 2, 3, 7], "insight": 2, "insist": [1, 6], "inspect": 1, "inspir": 2, "inst": 6, "inst_1": 6, "instal": [0, 6], "instanc": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "instanti": [2, 5, 6, 9], "instcommr": 5, "instead": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "instruct": [0, 1, 2, 9], "int": [5, 6, 7], "intact": 0, "integ": [1, 2, 4, 6, 7, 13], "integr": [2, 10, 13], "integral_add": 11, "integral_eq_sub_of_hasderivat": 11, "integral_hasstrictderivat_right": 11, "integral_id": 11, "integral_image_eq_integral_abs_det_fderiv_smul": 11, "integral_one_div": 11, "integral_prod": 11, "intend": [0, 1, 2, 5], "inter_def": 3, "inter_set": 9, "interact": [0, 5, 6, 7, 8, 11], "interchang": 1, "interconnect": 5, "interest": [1, 2, 3, 5, 6, 8, 9], "interestingli": [5, 7, 10], "interfac": 5, "interior": [5, 10], "interior_iinter_subset": 10, "interior_subset": 10, "intermedi": [1, 6, 8, 9], "intern": [2, 5, 7], "interpret": [0, 1, 4, 5, 7, 8, 9], "intersect": [1, 3, 5, 6, 7, 8, 9, 11], "interv": [4, 9, 11], "interval_cas": 4, "intervalintegr": 11, "intro": [0, 1, 2, 3, 4, 5, 6, 7, 9], "introduc": [0, 1, 2, 3, 4, 8, 9, 11], "introduct": [1, 2, 7, 9, 13], "introductori": 10, "intuit": [3, 9], "inv": [5, 6], "inv_def": 8, "inv_dia": 6, "inv_eq_of_dia": 6, "inv_eq_of_mul": 6, "inv_mem": 7, "inv_mul": 6, "inv_mul_cancel": [1, 5], "inv_mul_of_invert": 8, "invari": 11, "invers": [1, 3, 5, 6, 7, 8, 10, 11], "inverse_spec": 3, "invert": [6, 7, 8], "invertibleofisunitdet": 8, "invest": 5, "invfun": [3, 5, 8], "invfun_eq": 3, "invisibli": [5, 6], "invok": [0, 1, 9], "involv": [1, 2, 4, 5, 6, 7, 8, 9], "inv\u2081": 6, "inward": 2, "ioo": [9, 10], "ipo": 4, "irrat": 13, "irration": 4, "irreduc": [4, 5], "irreducible_iff_prim": 5, "irreflex": 2, "is_addit": 5, "isaddhaarmeasur": 11, "isaiah": 0, "isalgclos": 7, "isbigo_iff_isbigowith": 10, "isbigowith": 10, "isbigowith_iff": 10, "isclos": [9, 10], "isclosed_l": [9, 10], "iscompact": 9, "iscompact_icc": 9, "iscompact_univ": 9, "iscompl": 8, "iscoprim": [7, 8], "iscoprime_iff_add": 7, "iscoprime_iff_codisjoint": 7, "iscoprime_iff_exist": 7, "iscoprime_iff_sup_eq": 7, "iscoprime_inf": 7, "iscycl": 7, "isdomain": [2, 7], "iseqv": 6, "isintern": 8, "isinternal_submodule_iff_independent_and_isup_eq_top": 8, "islinear": 5, "islittleo_iff_forall_isbigowith": 10, "islocalmin": 10, "ismonoidhom\u2081": 6, "ismonoidhom\u2082": 6, "isn": [0, 2, 3, 4, 6], "isomorph": [5, 7, 8, 10], "isopen": 9, "isopen_compl_iff": 9, "isopen_empti": 9, "isopen_iff": 9, "isopen_iinter_of_finit": 9, "isopen_iunion": 9, "isopen_univ": 9, "iso\u2081": 7, "iso\u2082": 7, "isroot": [7, 8], "isroot_of_haseigenvalu": 8, "issu": [1, 4, 5, 6, 8, 9], "issubgroup": 7, "issubmodul": 8, "isunit": 7, "item": 9, "iter": 10, "iteratedfderiv": 10, "its": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "itself": [0, 2, 3, 5, 6, 7, 8, 9, 10], "iunion": 11, "j": [3, 7, 8], "jimmi": 0, "job": 1, "johan": 0, "john": 0, "join": [0, 1, 5], "jone": 0, "joseph": 0, "journei": 9, "juggl": 6, "julian": 0, "jump": [1, 4, 5, 9], "just": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "justif": [1, 2], "justifi": [0, 1, 2, 9], "k": [0, 2, 4, 5, 7, 8, 9, 10], "kabelo": 0, "keep": [1, 3, 5, 6, 7], "kei": [1, 4, 5, 7, 8, 9], "keith": 0, "ker": [7, 8], "ker_eq_bot": 8, "ker_eq_bot_iff": 7, "ker_le_ker_comp": 8, "ker_mkq": 8, "ker_pi_quotient_mk": 7, "ker_restrict": 7, "kernel": [7, 8], "keyboard": 1, "keyword": [1, 2, 4, 5], "kim": 0, "kind": [0, 1, 6, 8, 9], "knew": 9, "know": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "known": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "k\u00fclshammer": 0, "l": [0, 1, 8, 10, 11], "label": [1, 2], "lagrang": 7, "lake": 0, "lambda": [2, 5], "lambda_l": 5, "lambda_nonneg": 5, "languag": [0, 1, 2, 3], "larg": [0, 6, 9], "larger": [1, 9], "last": [1, 2, 3, 4, 5, 6, 7, 9], "later": [0, 1, 2, 4, 5, 6, 7, 8, 9], "latter": [5, 7, 9], "lattic": [1, 5, 6, 7, 9], "law": [1, 7], "layer": [6, 9], "lbf": 2, "lbg": 2, "lcm": 1, "lcm_zero_left": 1, "lcm_zero_right": 1, "ldot": [2, 3, 4], "le": [1, 5, 6], "le_abs_self": 2, "le_antisymm": [1, 2], "le_iff_exists_add": 9, "le_inf": 1, "le_inf_iff": 9, "le_min": 1, "le_mul_of_one_le_right": 5, "le_of_dvd": 4, "le_of_l": 6, "le_of_max_le_left": 2, "le_of_max_le_right": 2, "le_of_mul_le_mul_right": 5, "le_of_not_gt": 2, "le_opnorm": 10, "le_or_gt": 2, "le_principal_iff": 9, "le_refl": [1, 2], "le_sup": 4, "le_sup_left": 1, "le_sup_right": 1, "le_tran": [1, 2], "lead": [1, 2, 4, 5, 6, 7, 8, 9], "leader": 1, "lean": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "lean4": 1, "learn": [0, 1, 4, 5], "least": [1, 5, 6, 8, 9], "leav": [0, 1, 2, 3, 5, 6, 7], "lebesgu": 11, "led": 6, "left": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "left_distrib": [5, 6], "left_inv": [5, 8], "left_inv_eq_right_inv": 6, "left_inv_eq_right_inv\u2081": 6, "left_neg_eq_right_neg": 6, "leftinvers": 3, "leftinverse_invfun": 3, "legal": 1, "lemma": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13], "less": [1, 2, 3, 4, 5, 6, 7, 8, 9], "let": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "letter": [1, 5, 10], "level": [1, 2, 6, 8], "leverag": 9, "le\u2081": 6, "librari": [0, 1, 2, 3, 4, 5, 7, 9, 10], "life": [0, 2], "lift": [7, 8], "liftq": 8, "light": 5, "like": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "lim_": 9, "limit": [2, 6, 9], "linarith": [1, 2, 4, 5], "line": [0, 1, 2, 3, 4, 6, 7, 8], "linear": [1, 2, 5, 7, 9, 13], "linear_combin": 7, "linearcombin": 8, "linearcombination_apply_of_mem_support": 8, "linearcombination_repr": 8, "linearequiv": 8, "linearequivfunonfintyp": 8, "linearindepend": 8, "linearli": 8, "linearmap": 8, "linearord": 2, "linearorderedr": 5, "liner": 0, "linf": 5, "link": [5, 6], "list": [1, 2, 3, 4, 5, 8], "littl": [1, 2, 9, 10], "liu": 0, "live": [0, 5, 8], "ll": [0, 2, 4, 6, 9], "local": [1, 2, 6, 9, 10], "localinvers": 10, "lof": 8, "log": [1, 3, 11], "log_le_log": 1, "log_lt_log": 1, "logic": [0, 1, 3, 4, 5, 7, 8, 13], "logician": 1, "long": [1, 2, 3, 5, 6, 7, 8, 10], "longer": [0, 4, 5], "look": [1, 2, 3, 4, 6, 7, 8, 9], "loop": 4, "lose": 8, "loss": 4, "lot": [0, 1, 3, 5, 6, 7, 8, 9], "loud": 1, "lower": [1, 2, 4], "lowest": 4, "lr": 1, "lsmul": 8, "lt_ab": 2, "lt_asymm": 2, "lt_iff_le_and_n": 1, "lt_iff_le_not_l": 2, "lt_irrefl": [1, 2], "lt_of_le_of_lt": [1, 2], "lt_of_lt_of_l": 1, "lt_of_not_g": 2, "lt_succ_iff": 4, "lt_succ_of_l": 4, "lt_tran": [1, 2], "lt_trichotomi": 2, "lt\u2081": 6, "lu": 0, "lub": 1, "m": [0, 1, 2, 4, 6, 7, 8, 9, 10], "m_iunion": 11, "mac": [1, 2], "macbeth": 5, "machin": 8, "machineri": [5, 6, 8, 9], "maco": 0, "made": [1, 2, 3, 5, 8, 9], "magic": [2, 5, 6], "mai": [0, 1, 2, 3, 5, 6, 7, 8, 9, 10], "main": [2, 6, 8, 9, 10], "mainli": 7, "maintain": 1, "make": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "manag": [0, 1, 4, 5, 9], "mani": [1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 13], "manifest": [1, 9], "manipul": [2, 5, 7, 8, 9], "manner": [2, 5], "manual": [0, 3, 4], "map": [1, 2, 3, 5, 6, 7, 9, 13], "map_add": [6, 7, 8, 10], "map_comap_eq": 8, "map_eq": 9, "map_inv": 7, "map_inv_of_inv": 6, "map_le_iff_le_comap": 9, "map_map": 9, "map_mono": 9, "map_mul": [6, 7, 8], "map_on": [6, 7], "map_pow": 7, "map_smul": [8, 10], "map_zero": [6, 7], "mapq": 8, "mapsto": [1, 5], "map\u2082": 6, "marc": 0, "mario": 0, "mark": [0, 1, 2, 6, 9], "marker": 2, "marriag": 5, "martin": 0, "mascellani": 0, "mass": 11, "master": [0, 1, 4], "match": [1, 2, 5], "mathbb": [3, 4, 5, 7], "mathcal": [5, 10], "mathemat": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "mathematician": [4, 9], "mathematics_in_lean": 0, "mathfrak": 7, "mathieu": 0, "mathlib": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "matric": [1, 5, 7, 13], "matrix": 8, "matter": [1, 2], "matthew": 0, "mauricio": 0, "max": [1, 2, 6, 8, 9, 11], "maxim": 7, "maximum": [2, 4, 9], "mayb": 6, "mcdowel": 0, "mckinsei": 0, "mdvdn": 4, "mean": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "meaning": 8, "meaningless": 2, "meant": [0, 2, 6, 8], "meanwhil": [1, 4], "measur": [0, 5, 9, 10, 13], "measurableset": 11, "measurablespac": 11, "measure_eq_iinf": 11, "measure_iunion_l": 11, "measuretheori": 11, "mechan": [1, 2, 5], "mediat": 4, "medit": 8, "meet": [1, 2, 3, 5], "mehta": 0, "mem": [3, 8], "mem_": 4, "mem_ball_self": 9, "mem_bot": [7, 8], "mem_closedball_self": 9, "mem_closure_iff": 9, "mem_closure_iff_clusterpt": 9, "mem_closure_iff_nhds_basi": 9, "mem_closure_iff_seq_limit": 9, "mem_closure_of_tendsto": 9, "mem_comap": [7, 8], "mem_diff": 3, "mem_eras": 4, "mem_filt": 4, "mem_iff": 9, "mem_iint": 3, "mem_iinter\u2082": 3, "mem_image_of_mem": 3, "mem_inf": 8, "mem_insert": 4, "mem_insert_of_mem": 7, "mem_insert_self": 7, "mem_int": 4, "mem_inter_iff": 3, "mem_iunion": 3, "mem_iunion\u2082": 3, "mem_ker": [7, 8], "mem_map": [7, 8], "mem_map_of_mem": 8, "mem_nhds_iff": 9, "mem_of_dvd_prod_prim": 4, "mem_of_tendsto": 9, "mem_preimag": 8, "mem_rang": 7, "mem_sdiff": 4, "mem_setof": 3, "mem_sup": [7, 8], "mem_union": [3, 4], "member": [3, 9], "membership": [3, 4, 6, 7, 8], "mention": [2, 3, 5, 6, 7, 9], "menu": [0, 1], "meq": 4, "messag": 6, "messi": 5, "messier": 5, "meta": [2, 6], "metavari": 6, "method": [0, 2, 3, 4, 5], "metric": [1, 5, 10, 13], "metricspac": [1, 9, 10], "mf": 2, "mg": 2, "mge2": 4, "mgt2": 4, "mid": 5, "middl": [0, 1, 2, 9], "midpoint": 5, "might": [1, 2, 3, 4, 5, 7], "mil": 0, "min": [1, 2, 9, 11], "min_le_left": 1, "min_le_right": 1, "mind": [1, 2, 5, 6, 7], "mindich": 0, "minfac": 4, "minim": 8, "minimum": 9, "minor": [6, 10], "minpoli": 8, "mislead": 7, "miss": [1, 3, 4], "mission": 0, "mk": [5, 6, 7, 8, 9], "mk_appli": 8, "mk_eq_mk_of_basi": 8, "mk_surject": 7, "mkofmuleqon": 7, "mkofnhd": 9, "mkq": 8, "mltn": 4, "mne1": 4, "mnez": 4, "mod": 5, "mod_4_eq_3_or_mod_4_eq_3": 4, "mod_def": 5, "mod_lt": 4, "mode": [1, 2, 5], "model": [3, 8, 9], "modern": [5, 7], "modifi": 6, "modu": 1, "modul": [6, 7, 8], "modular": 1, "module\u2081": 6, "module\u2083": 6, "modulo": [1, 4, 5], "moiloa": 0, "moment": [1, 2, 5], "mono": 9, "monof": 2, "monoid": [2, 3, 4, 6, 8, 13], "monoidhom": 7, "monoidhomclass": 6, "monoidhomclass\u2081": 6, "monoidhomclass\u2082": 6, "monoidhomclass\u2083": 6, "monoidhom\u2081": 6, "monoid\u2081": 6, "monoid\u2082": 6, "monoid\u2083": 6, "monoton": [2, 6, 9], "monro": 0, "monticon": 0, "moral": [0, 5, 7], "more": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 13], "moreov": [0, 1, 4, 5, 9], "morphism": [5, 8, 10, 13], "morrison": 0, "most": [1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "mostli": 7, "motiv": [2, 8], "move": [0, 1, 2, 6, 8, 9], "mp": [1, 2, 3, 4, 9], "mpr": [1, 2, 5, 9], "much": [0, 2, 4, 6, 7, 8, 9, 10], "mul": [4, 5, 6, 9], "mul_add": [0, 1, 4, 6], "mul_appli": 8, "mul_assoc": [1, 2, 4, 5, 6, 7], "mul_assoc\u2083": 6, "mul_comm": [1, 2, 4, 5, 6, 7], "mul_def": 5, "mul_div_cancel": 4, "mul_div_cancel\u2080": 2, "mul_eq_comp": 8, "mul_im": 5, "mul_inv": [6, 7], "mul_inv_cancel": [1, 5, 7], "mul_inv_cancel_right": 5, "mul_inv_rev": 1, "mul_le_inf": 7, "mul_le_left": 7, "mul_le_mul": 2, "mul_le_right": 7, "mul_left_cancel\u2083": 6, "mul_left_comm": 4, "mul_left_not_lt": 5, "mul_lt_mul_right": 2, "mul_mem": [6, 7], "mul_mod": 4, "mul_mod_mod": 4, "mul_mod_right": 4, "mul_nonneg": 1, "mul_on": [1, 5, 6, 7], "mul_po": [1, 4], "mul_r": 5, "mul_right_cancel\u2083": 6, "mul_right_inj": 4, "mul_smul": [6, 7], "mul_sub": 1, "mul_sum": 5, "mul_zero": [1, 5, 6], "mulact": 7, "mulequiv": 7, "muloneclass": 6, "multilinear": 10, "multipl": [1, 2, 3, 4, 5, 6, 7, 8, 10], "multipli": [5, 8], "multiset": 7, "multivari": 7, "mulvec": 8, "mulzeroclass": 6, "mundan": 2, "must": [1, 5, 6, 8, 9], "mvpolynomi": 7, "my_fil": 0, "my_lemma": 2, "my_lemma2": 2, "my_lemma3": 2, "my_lemma4": 2, "my_squar": 5, "myab": 2, "myelement": 7, "mygroup": 7, "mymap": 7, "mymorph": 7, "mynat": 4, "mynewmorph": 7, "mypoint1": 5, "mypoint2": 5, "mypoint3": 5, "myre": 1, "mysmul": 6, "mysquar": 5, "mysteri": [1, 5, 6], "mz": 4, "m\u02e3": 7, "n": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "n_p": 9, "n_q": 9, "na": 2, "naiv": [6, 9], "name": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "namespac": [1, 2, 3, 4, 5, 7, 8, 9], "nash": 0, "nat": [0, 1, 2, 3, 4, 5, 7, 9], "natab": 5, "natabs_mul": 5, "natabs_norm_mod_lt": 5, "natabs_of_nonneg": 5, "natal": 0, "natcast_natab": 5, "natdegre": 7, "natdegree_comp": 7, "natdegree_mul": 7, "natur": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "nb": 2, "ne": [4, 5], "nearbi": [1, 4], "nearest": 5, "nebot": 9, "nebot_of_l": 9, "necessari": [0, 2, 4, 5, 7, 8], "necessarili": [1, 8, 11], "need": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "neg": [5, 6, 9, 11], "neg_add": 6, "neg_add_cancel": [1, 5], "neg_add_cancel_left": 1, "neg_def": 5, "neg_eq_of_add_eq_zero": 1, "neg_im": 5, "neg_le_abs_self": 2, "neg_mem": 7, "neg_neg": 1, "neg_r": 5, "neg_zero": 1, "negat": [1, 5, 13], "negsucc": 6, "neighborhood": 9, "neither": [3, 5, 6, 8], "neq": 4, "nest": [1, 2], "net": 1, "neutral": [6, 7], "never": [0, 6], "new": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "newcom": 0, "next": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "nge": 2, "nhd": 9, "nhds_basis_bal": 9, "nhds_basis_closedbal": 9, "nhds_basis_ioo_po": 9, "nhds_basis_open": 9, "nhds_induc": 9, "nhds_mkofnhd": 9, "nhds_prod_eq": 9, "nice": [1, 2, 4, 6, 7, 8, 9], "nicer": [5, 7, 9], "nicola": 0, "nineteenth": 3, "nna": 2, "nnc": 2, "nnez": 4, "nnf": 2, "nng": 2, "nnz": 4, "non": [1, 3, 6, 7, 8, 9, 11], "noncomm_r": 1, "noncomput": [3, 5, 7, 8], "nonconstruct": 7, "nondecreas": [2, 4], "nondistribut": 1, "nonempti": [3, 7, 9], "nonempty_interior_of_iunion_of_clos": 10, "nonexist": 2, "nonneg": [1, 5], "nonneg_of_mul_nonneg_left": 1, "nontrivi": [2, 3, 4, 5, 8, 9, 10], "nontriviallynormedfield": [10, 11], "nonzero": [2, 4, 5, 11], "nor": [3, 5, 8], "norm": [2, 5, 9, 13], "norm_add_l": 10, "norm_conj": 5, "norm_eq_zero": [5, 10], "norm_mod_lt": 5, "norm_mul": [5, 10], "norm_nonneg": [5, 10], "norm_num": [1, 2, 4, 5, 8], "norm_po": 5, "norm_smul": 10, "norm_y_po": 5, "normal": 7, "normedaddcommgroup": [10, 11], "normedaddgroup": 10, "normedfield": 10, "normedgroup": 10, "normedspac": [10, 11], "not_even_iff": 3, "not_even_iff_odd": 3, "not_imp_self": 3, "not_le_of_gt": 2, "not_lt_of_g": [2, 4, 5], "not_monotone_iff": 2, "not_norm_mul_left_lt_norm": 5, "not_not": 2, "notat": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "note": [1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "noth": [1, 2, 3, 4, 5, 6, 7], "notic": [1, 2, 3, 4, 5, 7, 9], "notin": 3, "notion": [1, 2, 3, 4, 5, 7, 8, 9, 10, 11], "noun": 6, "now": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "nozerodivisor": 7, "np": 4, "npow_nz": 4, "npowz": 4, "nsmul": [5, 6], "nsmul_succ": 6, "nsmul_zero": 6, "nsmulrec": 5, "nsmul\u2081": 6, "nsqr_nez": 4, "nt": 2, "nth_rw": 1, "nuccio": 0, "number": [0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 13], "numer": [1, 4, 5], "nut": 1, "n\u2080": 2, "n\u2081": 2, "o": 10, "obfusc": 9, "object": [0, 1, 2, 3, 4, 5, 7, 8, 13], "observ": [2, 4, 9], "obtain": [1, 2, 4, 5, 9, 10], "obviou": [0, 4, 5, 6], "occasion": 9, "occur": 4, "occurr": 1, "odd": [1, 2, 3, 4, 8], "odd_iff": 3, "of_fintype_basi": 8, "of_foral": 9, "of_le_succ": 4, "of_map": 9, "ofbiject": [7, 8], "off": [2, 3, 4], "offend": 6, "offer": [0, 2, 5, 9], "ofnat": 6, "ofnat_l": 5, "ofnat_lt": 5, "ofrealhom": 7, "often": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "og": 2, "old": [2, 5, 6, 8], "oliv": 0, "omit": 5, "onc": [1, 2, 3, 4, 5, 6, 7, 9, 11], "one": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "one_add_one_eq_two": 1, "one_def": 5, "one_dia": 6, "one_eq_top": 7, "one_fin_two": 8, "one_im": 5, "one_mem": [6, 7], "one_mul": [1, 2, 5, 6], "one_r": 5, "one_smul": [6, 7], "oner": 1, "ones": [0, 1, 2, 3, 5, 8, 11], "one\u2081": 6, "one\u2082": 6, "onli": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "onlin": 0, "onto": [7, 8], "open": [0, 1, 2, 3, 4, 5, 7, 8, 10, 11], "oper": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "opnorm_le_bound": 10, "opnorm_le_of_shel": 10, "opportun": [7, 9], "opposit": [6, 9], "optim": [6, 8, 11], "option": [1, 2, 4, 5, 6, 9], "orbit": 7, "orbitequivquotientstabil": 7, "orbitrel": 7, "order": [1, 2, 3, 4, 5, 6, 8, 9, 10], "orderedcanceladdcommmonoid": 2, "orderedcommmonoid\u2081": 6, "orderpreshom": 6, "orderpreshomclass": 6, "orderpresmonoidhom": 6, "ordinari": [1, 2, 4, 5, 7, 8, 9], "ordinarili": [4, 5], "organ": 0, "organiz": 1, "orient": 5, "origin": [0, 1, 5, 7], "other": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "otherwis": [1, 2, 3, 4, 5, 7], "ott": 0, "our": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "ourselv": [4, 6], "out": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "outer": 1, "outermost": 3, "outlin": [1, 2, 4, 9], "outparam": 6, "output": [1, 7], "outsid": [1, 4, 8], "over": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "overlap": [6, 7], "overload": 3, "overview": 13, "own": [0, 1, 4, 5, 6], "p": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "p4": 4, "p4eq": 4, "p_1": 4, "p_i": [4, 9], "p_k": 4, "p_n": 4, "p_ne_zero": 7, "packag": [7, 8], "page": [0, 1, 4], "pai": [1, 2, 6, 7, 9], "pain": 7, "pair": [1, 2, 4, 5, 7, 9], "pairwis": [8, 11], "pairwisedisjoint": 8, "panel": 0, "paper": [2, 3, 5, 7, 8, 9, 11], "paquet": 0, "paradox": [8, 9], "paragraph": 9, "parallel": 8, "paramet": [5, 6], "parent": 6, "parenthes": [1, 2, 3, 4], "pariti": 0, "parity_simp": 0, "pars": [1, 3, 7], "part": [1, 2, 3, 4, 5, 6, 8, 9, 11], "partial": [0, 1, 2, 3, 5, 6, 7, 8], "partialord": [1, 2], "partialorder\u2081": 6, "particular": [1, 2, 5, 6, 7, 8, 9], "partit": 7, "partli": [1, 6, 7], "pass": [1, 5], "past": [0, 1, 7], "path": 6, "patholog": 9, "pattern": [1, 2, 3, 5, 6], "payoff": 5, "pdf": 0, "pdvd": 4, "pedro": 0, "peel": 2, "pen": [2, 7], "peopl": [0, 1], "perform": [1, 2, 3], "perm": [5, 7], "permgroup": 5, "permiss": 1, "permut": [4, 7], "person": 0, "perspicu": 2, "phenomenon": 3, "phrase": [0, 1, 2, 4, 5, 8], "pi": [7, 8, 9], "pick": [0, 6], "pictur": [4, 5, 7], "piec": [1, 4, 5, 6, 7, 9], "pierpaolo": 0, "pietro": 0, "pim": 0, "pinot": 7, "piotrowski": 0, "place": [0, 1, 2, 5, 8, 9], "placehold": 2, "placement": 4, "plai": [1, 3, 4, 6, 7, 8, 9], "plan": [1, 6, 9], "plane": 9, "plausibl": 3, "ple": 4, "pltn": 4, "pne3": 4, "point": [0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11], "pointwis": [5, 9, 10], "polynomi": [5, 8], "ponen": 1, "poor": 6, "pop": 0, "port": 0, "posit": [1, 3, 4, 5, 9, 11], "possibl": [1, 2, 3, 4, 5, 7, 9], "possibli": 5, "postfix": 6, "pos\u2080": 2, "potscrubb": 0, "pow_eq": 4, "pow_eq_zero": [2, 4], "pow_succ": 4, "pow_two": [1, 4], "pow_two_le_fac": 4, "pow_two_nonneg": [1, 2], "power": [0, 1, 3, 4, 5, 6, 8], "pp": 4, "pq": 8, "practic": [1, 2, 3, 6, 7, 9], "pragmat": 5, "pre": [2, 8], "preal": 5, "preced": [4, 7], "precis": [1, 3, 7, 8, 9, 10], "precondit": 9, "pred": 4, "predecessor": 4, "predic": [2, 3, 4, 6, 7, 8, 9, 10], "prefer": [0, 1, 2, 3], "prefix": [4, 6, 7], "preimag": [3, 7, 8, 9], "preliminari": 6, "prematur": 6, "preorder": [2, 6, 9], "preorder\u2081": 6, "presenc": 6, "present": [1, 2, 4, 7, 9], "presentedgroup": 7, "preserv": [4, 6, 8, 9], "preserves_mul": 5, "press": [0, 8], "presuppos": 0, "pretend": [6, 8], "pretti": [2, 6, 7, 8, 9], "previou": [1, 2, 3, 5, 6, 7, 9, 10, 11], "previous": 6, "price": 9, "primari": 6, "primarili": [6, 7, 9], "prime": [1, 2, 3, 5, 6, 7, 8, 13], "prime_def_lt": 4, "prime_iff": 3, "prime_of_mem_primefactorslist": 4, "prime_p": 4, "prime_q": 4, "prime_thre": 4, "prime_two": 4, "prime_x": 3, "primefactorslist": 4, "primefactorslist_uniqu": 4, "primes_infinit": 4, "primes_mod_4_eq_3_infinit": 4, "primit": [2, 3], "princip": 9, "principl": [1, 2, 3, 4, 6, 8, 10], "print": [0, 3, 4, 5, 11], "priori": [6, 8], "prioriti": 5, "probabl": [1, 5, 6, 9], "problem": [3, 4, 5, 6, 9], "proce": [4, 6], "procedur": [4, 6], "proceed": 7, "prod": [4, 7, 8, 9, 11], "prod_": 4, "prod_empti": 4, "prod_insert": 4, "prod_map": 9, "prod_mk": 9, "prod_po": 4, "prod_primefactorslist": 4, "prod_range_succ": 4, "prod_range_zero": 4, "prodcongr": 7, "prodequivpi": 7, "prodmap": 8, "produc": [1, 2, 7, 10], "product": [2, 4, 5, 6, 7, 9, 11], "profici": 4, "program": [0, 1, 2], "progress": [0, 1, 5, 7], "prohibit": 9, "proj": 8, "project": [0, 4, 5, 7, 8, 9], "projector": 7, "promin": 7, "promis": [6, 8, 9], "promot": 1, "proof": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "prop": [0, 2, 3, 4, 5, 6, 7, 8, 9, 11], "propag": 6, "properti": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "proposit": [0, 2, 3, 4, 5], "protect": 5, "provabl": [1, 3, 6, 9], "prove": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13], "proven": [7, 8], "provid": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "proxi": 5, "pseudoemetricspac": 9, "pseudometricspac": 9, "psycholog": 6, "pull": [0, 7, 9], "pullback": [7, 9], "pun": 2, "pure": [1, 9], "pure_le_nhd": 9, "purpos": [1, 2, 3, 4, 5, 6, 8, 9], "push": [2, 4, 7, 9], "push_neg": [2, 3, 4], "push_pul": 9, "pushforward": [7, 9], "put": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "q": [2, 4, 5, 6, 7, 8, 9], "qk": 4, "quad": 5, "quadrat": 5, "quantifi": [1, 3, 4, 5, 7, 9, 13], "quantiti": 9, "quest": 6, "question": [0, 4, 6, 9, 11], "quick": [4, 7, 8, 10], "quicker": 0, "quickli": [3, 7, 11], "quirki": 4, "quit": [2, 6, 9], "quot": [5, 8, 9], "quotequivofeq": 7, "quotient": [4, 5, 6, 9, 13], "quotient_mul_add_remainder_eq": 5, "quotient_zero": 5, "quotientgroup": 7, "quotientinfringequivpiquoti": 7, "quotientkerequivrang": 7, "quotientmap": 7, "quotientmonoid": 6, "quotientmulequivofeq": 7, "quotkerequivrang": 8, "r": [1, 2, 4, 5, 6, 7, 8, 9], "r_wellfound": 5, "radiu": 9, "raini": 3, "rais": [1, 4], "random": 6, "rang": [0, 2, 3, 4, 7, 8, 9], "range_eq_map": 8, "range_eq_top": 8, "range_mkq": 8, "rank": 8, "rare": 6, "rather": [0, 1, 2, 4, 5, 6, 7, 8, 9], "ration": [1, 2, 4, 9], "rb": 9, "rcase": [2, 3, 4, 9], "rclike": 10, "re": [4, 5], "reach": [2, 6], "read": [0, 1, 4, 5, 6, 7, 8, 9], "readabl": [1, 2, 3, 8, 9], "reader": [1, 8, 9], "readi": [4, 6, 7, 8, 9, 10], "real": [1, 2, 3, 4, 5, 6, 8, 9, 10, 11], "real_norm_l": 10, "realli": [1, 2, 3, 4, 6, 7, 8, 9], "reason": [0, 1, 2, 4, 5, 6, 7, 8, 9], "rec_on": 9, "recal": [1, 2, 4, 5, 7, 9, 11], "recaptur": 9, "recast": 9, "recent": 5, "recogn": [1, 2, 4, 5, 6, 9], "recommend": [0, 1, 3], "recon": 9, "reconcil": 2, "record": [5, 6, 8], "recov": 9, "recurs": [2, 3, 5, 13], "redefin": [5, 6], "reduc": [0, 2, 3, 4, 5], "reduct": [2, 3, 5], "redund": [1, 5, 8, 9, 11], "refer": [0, 1, 2, 4, 5, 6, 8, 9, 10], "refin": [4, 10], "refl": [2, 3, 5, 6, 7, 8], "refl_tran": 5, "reflect": 2, "reflex": [1, 2, 5], "reformul": 9, "refus": [6, 9], "regiment": 0, "region": 3, "regist": [5, 6, 7, 8], "regular": [6, 9], "regularspac": 9, "rel": [3, 5, 8], "relat": [1, 2, 3, 5, 6, 7, 8, 9, 10, 11], "relatedli": 9, "relationship": [3, 4], "relativ": 3, "relev": [0, 1, 2, 4, 5, 6, 7, 8, 9], "reli": [1, 2, 5, 9], "remain": [0, 1, 2, 3, 5, 6, 9], "remaind": [4, 5, 7], "remainder_lt": 5, "remark": [5, 6], "rememb": [1, 2, 3, 4, 5, 6, 7, 8, 9], "remov": [4, 9], "renam": 0, "render": [2, 4], "repeat": [1, 4, 5, 6], "repeatedli": [2, 9], "repetit": [1, 6], "replac": [0, 1, 2, 3, 4, 6, 7, 8], "replai": 0, "report": 1, "repositori": [0, 1], "repr": 8, "repres": [0, 1, 2, 3, 4, 5, 6, 10], "represent": [3, 4, 5, 8], "reproduc": 5, "reprov": [1, 7, 8], "requir": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "resolut": 6, "resolve_left": 3, "resourc": 0, "resp": 8, "respect": [1, 2, 3, 4, 5, 7, 8, 9], "respons": [0, 1], "rest": [2, 3, 5, 7, 9], "restat": [2, 6, 7, 8], "restor": 6, "restrict": [3, 4, 7, 9], "result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "retri": 6, "return": [0, 2, 3, 4, 5, 7, 8, 9], "reus": 6, "reusabl": 6, "reveal": [1, 8], "revers": [1, 2, 3, 5, 9], "revert": 4, "review": [7, 9], "rewrit": [0, 1, 2, 3, 4, 5, 6, 8, 9], "rewritten": 3, "rfl": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "rich": [5, 6], "rid": 2, "right": [1, 2, 3, 4, 5, 6, 8, 9, 10], "right_distrib": [5, 6], "right_inv": [5, 8], "rightinvers": 3, "ring": [0, 1, 2, 3, 4, 5, 6, 8, 13], "ringequiv": 7, "ringhom": [6, 7], "ringhomclass\u2083": 6, "ringhom\u2081": 6, "ring\u2081": 6, "ring\u2083": 6, "rintro": [0, 2, 3, 4, 7, 8, 9], "rise": [4, 6, 7], "road": 5, "robust": [5, 6], "role": [4, 5, 8, 9], "roll": 10, "rolland": 0, "roman": 5, "root": [5, 6, 7, 8, 13], "roots_mul": 7, "roots_x_sub_c": 7, "roughli": [2, 3, 4], "round": [0, 1, 5], "routin": 2, "row": 8, "rpo": 9, "rule": [0, 2, 4, 5, 6, 8, 9], "run": 0, "rush": 0, "russel": 8, "rw": [0, 2, 3, 4, 5, 6, 7, 8, 9, 13], "rwa": [3, 4, 5], "r\u02e3": 7, "s_": 3, "s_0": [2, 3], "s_1": 2, "s_2": 2, "s_n": [2, 3], "sa": 2, "sad": 9, "safe": [6, 7], "safer": 7, "sage": 8, "sai": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "said": [0, 2, 4, 5], "sake": [1, 4], "salient": 9, "same": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "satisfi": [1, 3, 4, 5, 6, 9, 10], "save": 2, "saw": [1, 5, 6, 7, 8, 9], "sb": 2, "sb_fun": 3, "sb_inject": 3, "sb_right_inv": 3, "sb_surject": 3, "sbaux": 3, "sbfun": 3, "sbset": 3, "scalar": [5, 6, 7, 8, 10], "scale": 3, "scari": 5, "scheme": 5, "schroeder_bernstein": 3, "schr\u00f6der": 13, "scienc": 6, "scientist": 2, "scope": [1, 2, 3, 5, 7, 8], "scratch": 2, "script": 1, "search": [4, 5, 6], "second": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "secretli": 8, "section": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "see": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "seek": 5, "seem": [1, 2, 4, 6, 9, 10], "seen": [0, 1, 2, 4, 5, 6, 7, 8, 9], "segment": [9, 11], "select": [0, 9], "self": 6, "self_of_nhd": 9, "self_sub": 1, "self_trans_symm": [5, 7, 8], "selfequivsigmaorbit": 7, "selfmodul": 6, "semi": [6, 7, 8], "semicolon": [2, 4], "semigroup": 6, "semigroup\u2081": 6, "semigroup\u2082": 6, "semigroup\u2083": 6, "semir": [6, 7], "send": [7, 8, 11], "sens": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10], "sensibl": 9, "sent": [7, 9], "separ": [0, 1, 2, 4, 5, 8], "sequenc": [3, 6, 9, 10, 13], "seri": 7, "seriou": [4, 6, 9], "serv": [1, 3, 4, 5, 11], "set": [0, 1, 2, 4, 5, 6, 7, 10, 11, 13], "set_opt": 6, "setco": 6, "setintegral_const": 11, "setlik": 6, "setminu": 3, "setoid": [6, 7], "sets_of_superset": 9, "setub": 2, "setup": [7, 8], "seurin": 0, "sever": [6, 8, 9, 11], "shade": 3, "shame": 6, "sharp": 0, "shift": [0, 1, 6, 9], "short": [0, 1, 2, 3, 4, 5, 8], "shorten": [1, 2, 7], "shorter": [1, 3, 4, 7, 9], "shot": 9, "should": [0, 1, 2, 3, 4, 5, 6, 7, 9, 10], "shouldn": [8, 9], "show": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "shown": [1, 5, 10, 11], "side": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "sight": [2, 6], "sigma": [5, 11], "sigmafinit": 11, "sign": 9, "signatur": 6, "signific": 3, "silent": [5, 6], "silli": 6, "silva": 0, "similar": [1, 2, 3, 5, 6, 7, 8, 9], "similarli": [2, 3, 4, 5, 7, 8], "simp": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10], "simp_rw": 7, "simpa": [4, 7, 10], "simpl": [2, 4, 5, 6, 10], "simpler": [6, 8], "simplex": 5, "simpli": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "simplif": [2, 3, 4], "simplifi": [0, 2, 3, 4, 5, 9, 11], "sin": [2, 10], "sinc": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "singl": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10], "singleton": 4, "sinter": 3, "sinter_eq_biint": 3, "situat": [1, 3, 6, 7, 9], "size": 8, "skeleton": [5, 8, 9], "sketch": [2, 3, 4, 9], "skill": [0, 1, 2, 3, 4], "slick": 2, "slight": 3, "slightli": [1, 6, 7, 8, 9, 10], "slow": 9, "small": [0, 2, 4, 5, 9], "smaller": [3, 4, 9], "smallest": [4, 6, 8, 9], "smart": 4, "smul": [5, 6, 7, 8], "smul_add": [6, 8], "smul_comm": 8, "smul_distrib": 5, "smul_mem": 8, "smul\u2083": 6, "snd": [5, 8, 9], "snippet": [2, 4, 5, 7, 8], "so": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "solut": [0, 1, 4, 6], "solv": [0, 1, 2, 3, 4, 5, 6, 8, 9], "some": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "somehow": [7, 8], "someth": [0, 1, 2, 4, 6, 8, 9], "sometim": [1, 2, 3, 4, 5, 6, 7, 8, 9], "somewhat": [1, 3, 9], "somewher": 9, "soon": [0, 2, 6, 7, 8, 9], "sophist": 9, "sorri": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "sort": [1, 3, 4], "sosi": 2, "sosx": 2, "sound": [3, 5, 6], "sourc": [2, 9], "space": [1, 2, 3, 5, 6, 7, 11, 13], "span_eq": 8, "span_induct": 8, "span_l": 8, "span_union": 8, "speak": [2, 5, 7, 9], "special": [3, 4, 5, 6, 7, 8, 9, 11], "specif": [0, 1, 3, 4, 5, 6], "specifi": [1, 2, 3, 4, 5, 8, 9, 10, 11], "spell": [8, 9], "split": [1, 2, 3, 4], "spot": 2, "sq_ab": 5, "sq_add_sq_eq_zero": 5, "sq_nonneg": 1, "sqr_eq": 4, "sqrt": [2, 3, 4, 5], "squar": [1, 2, 4, 5, 6, 7, 8], "squiggli": 2, "ss": 3, "ssubt": 3, "stabil": 7, "stabl": 8, "stage": [2, 5, 6], "stai": 5, "stand": [1, 2, 4, 5, 6, 7, 8, 9, 10], "standard": [4, 5, 6, 9], "standardsimplex": 5, "standardtwosimplex": 5, "start": [1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 13], "state": [0, 1, 2, 3, 4, 6, 7, 8, 9, 10], "statement": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "stdsimplex": 5, "steep": 0, "steinhau": 10, "step": [0, 1, 2, 3, 4, 5, 6], "steven": 0, "stick": [1, 2, 9, 10], "still": [0, 1, 2, 3, 4, 5, 6, 8, 9, 11], "stipul": 10, "stop": 6, "store": 5, "stori": [6, 8], "str": 5, "straightforward": [2, 6], "strang": [2, 4, 7, 8], "strategi": [1, 2, 4], "strength": 1, "strengthen": [1, 2, 4], "stretch": [4, 5], "strict": [1, 2], "stricter": 10, "strictli": [1, 2, 10], "strictmono": 9, "strictorderedr": 1, "strike": [1, 2], "strong": [2, 4], "strong_induction_on": 4, "stronger": 9, "strongli": 0, "stronglymeasurableatfilt": 11, "struc": 5, "structur": [2, 4, 6, 7, 9, 10, 11, 13], "stuck": 6, "studi": [6, 9], "style": [0, 1], "sub": [3, 9, 11, 13], "sub_add_cancel": 1, "sub_eq_add_neg": 1, "sub_self": [1, 2], "sub_sub": 1, "subercaseaux": 0, "subgoal": 2, "subgroup": 6, "subgroupclass\u2081": 6, "subgroupofmulact": 7, "subgroup\u2081": 6, "subject": 5, "submodul": [7, 8], "submodule_independ": 8, "submodule_isup_eq_top": 8, "submonoid": [6, 7], "submonoidclass\u2081": 6, "submonoid\u2081": 6, "submonoid\u2081monoid": 6, "subobject": 6, "subproof": 1, "subr": 6, "subscript": [1, 8], "subsequ": [2, 4, 9], "subset": [1, 2, 3, 5, 9, 10], "subset_def": 3, "subset_iff": 4, "subspac": [1, 6, 13], "substant": 4, "substanti": 0, "substitut": [0, 2], "subsum": 4, "subtl": [5, 7, 8, 9], "subtleti": [6, 7, 8], "subtract": [1, 4, 5], "subtyp": [5, 6, 7, 8, 9], "succ": [4, 6], "succ_add": 4, "succ_le_succ": 4, "succ_mul": 4, "succ_ne_zero": 4, "succ_po": 4, "succe": 6, "success": 6, "successor": [4, 8], "suffic": [1, 2, 3, 7, 9], "suffici": [4, 9], "suggest": [0, 2, 4, 5, 8, 9], "suitabl": [0, 1, 2, 5, 9], "sum": [1, 2, 4, 5, 6, 7, 9], "sum_add_distrib": 5, "sum_eq": 5, "sum_eq_on": 5, "sum_id": 4, "sum_mul": 5, "sum_range_succ": 4, "sum_range_zero": 4, "sum_repr": 8, "sum_sqr": 4, "summand": 8, "summat": 4, "sumofsquar": 2, "sumofsquares_mul": 2, "sunion": 3, "sunion_eq_biunion": 3, "sup": [1, 4, 9], "sup_assoc": 1, "sup_comm": 1, "sup_eq_closur": 7, "sup_eq_top": 8, "sup_inf_left": 1, "sup_inf_right": 1, "sup_inf_self": 1, "sup_l": 1, "superfici": 9, "superscript": 9, "supersed": 8, "suppli": 5, "support": [0, 1, 2, 3, 4, 5, 6, 8, 9], "suppos": [1, 2, 3, 4, 5, 9], "suppress": 1, "supremum": [1, 4, 6, 7, 8], "sure": [0, 1, 2, 3, 5, 6, 7, 8], "surject": [2, 3, 7, 8, 9], "surjf": [2, 3], "surjg": 2, "surpris": 6, "surprisingli": [5, 6], "swap": 5, "swapxi": 5, "sweet": 3, "switch": [1, 6], "sylow": 7, "symbol": [1, 2, 5, 6, 7], "symm": [3, 4, 5, 6, 7, 8, 9, 10], "symmetr": [2, 3, 7], "symmetri": [3, 6], "synonym": 7, "syntact": 2, "syntax": [0, 1, 2, 4, 6, 8], "synth": 6, "synthes": [5, 6], "synthesi": 8, "synthinst": 6, "system": [3, 4, 5, 6, 8], "s\u00e1nchez": 0, "s\u02e3": 7, "s\u1d9c": [9, 11], "s\u2081": 6, "s\u2082": 6, "t": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "t2space": 9, "t3space": 9, "t_": 9, "t_3": 9, "t_x": 9, "t_y": 9, "t_z": 9, "tab": [1, 3, 4], "tackl": 6, "tactic": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "tag": [2, 3, 6], "take": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "taken": [1, 2], "takeshi": 0, "talk": [4, 7, 8, 9, 10], "tantamount": [1, 3], "target": [1, 6, 7, 8, 9, 11], "task": [0, 2, 4, 5, 6, 9], "taught": 7, "tauto": 4, "tautologi": 4, "teach": 0, "tear": 6, "technic": [1, 5, 6, 8], "techniqu": [2, 9], "technologi": 6, "tediou": [1, 2, 6], "tell": [0, 2, 3, 4, 5, 6, 7, 8], "temporarili": [1, 2], "tempt": 6, "tend": [1, 9], "tendsto": [9, 11], "tendsto_attop": 9, "tendsto_congr": 9, "tendsto_iff": 9, "tendsto_integral_of_dominated_converg": 11, "tendsto_nhds_uniqu": 9, "tendsto_pow_attop_nhds_zero_of_lt_on": 9, "tendsto_right_iff": 9, "tendsto_subseq": 9, "tendsto\u2081": 9, "tendsto\u2082": 9, "term": [0, 1, 2, 3, 4, 5, 7, 8, 9], "terminologi": [5, 8], "terraf": 0, "ters": 6, "test": 4, "text": [0, 3, 5, 9], "textbook": [0, 1, 2], "th": [4, 8], "than": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "thank": 6, "thei": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "them": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "theme": 3, "themselv": [0, 4, 5], "theorem": [0, 2, 4, 5, 7, 8, 9, 10, 11, 13], "theoret": [2, 3, 8, 9], "theori": [0, 1, 2, 3, 6, 7, 8, 9, 10, 13], "therefor": [1, 4, 5, 8, 9], "thereof": 0, "thi": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "thing": [0, 1, 2, 3, 4, 5, 6, 8, 9], "think": [0, 1, 2, 3, 4, 5, 6, 8, 9, 10], "third": [1, 2, 3, 5, 9], "thoma": 0, "thorough": 0, "those": [0, 1, 2, 3, 5, 6, 7, 8, 9, 10], "though": [2, 3, 4, 5], "three": [1, 2, 4, 5, 7, 9], "through": [0, 1, 3, 4, 5, 6, 7, 8, 9], "thu": [1, 3, 4, 5, 9], "thumb": 4, "tighter": [1, 3], "tightli": 5, "time": [1, 4, 5, 6, 8, 9, 10, 11], "timesav": 1, "tiresom": 9, "to_addit": 6, "to_localinvers": 10, "toaddcommgroup\u2083": 6, "toaddgroup\u2083": 6, "todiaoneclass\u2081": 6, "todia\u2081": 6, "tofun": [5, 6, 8], "togeth": [1, 2, 3, 4, 5, 7, 9], "togroup": 7, "tomatrix": 8, "tomatrix_comp": 8, "tomatrix_id": 8, "tomatrix_mulvec_repr": 8, "tomodul": 8, "tomonoidhom\u2081": 6, "tomuloneclass": 6, "too": [0, 1, 3, 5, 6, 7, 8, 9], "toohei": 0, "tool": [0, 1, 5, 6], "toone\u2081": 6, "top": [0, 6, 7, 8, 9, 10], "topermhom": 7, "topic": [4, 5, 6, 7, 8], "topolog": [5, 6, 10, 13], "topologi": [1, 5, 6, 10, 13], "topologicalspac": [9, 10], "toreal": 11, "tortuou": 8, "tosemigroup\u2081": 6, "tosmul\u2083": 6, "total": 1, "tour": [9, 10], "toward": 7, "trace": [6, 8], "tradeoff": 3, "tradition": 7, "train": [1, 6], "tran": [1, 2, 4, 5, 6, 7, 8], "trans_assoc": 5, "trans_refl": 5, "transform": [2, 3], "transit": [1, 2, 5, 9], "translat": [4, 6, 7, 9], "transpos": 8, "trap": 6, "treat": [2, 3, 5, 6, 7, 9, 10], "treatment": 7, "tri": [1, 2, 4, 6], "triangl": [1, 2, 5], "trick": [1, 2, 4, 6, 10], "tricki": [2, 3, 4, 6, 7], "trigger": [6, 8], "tripl": 3, "trivial": [3, 4, 7, 8, 9], "troubl": [2, 3, 5], "true": [1, 2, 3, 6, 8, 9], "truncat": 4, "trust": 8, "truth": [1, 4], "try": [0, 1, 2, 3, 4, 5, 6, 8, 9], "tucker": 0, "tupl": 5, "turn": [2, 3, 4, 5, 6, 8, 9, 10], "tutori": 0, "twice": [0, 1, 9], "two": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "two_l": 4, "two_le_of_mod_4_eq_3": 4, "two_mul": 1, "ty": 7, "type": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "typeclass": [6, 8], "typic": [1, 7], "u": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "u_2": 8, "u_n": 8, "ubf": 2, "ubfa": 2, "ubg": 2, "ubgb": 2, "ulequiv": 7, "ultim": 0, "un": 3, "unapp": 1, "unbundl": 6, "unchang": [1, 2], "uncom": 1, "uncount": 9, "uncurri": 9, "under": [5, 6, 7, 8, 9], "underli": [0, 1, 5, 6, 7, 8], "underneath": [1, 3], "underscor": [1, 2, 3, 8], "understand": [0, 2, 3, 4, 5, 6, 7, 8, 9], "understood": [4, 9], "unfold": [1, 2, 3, 4, 5, 9], "unfortun": 7, "unicod": [1, 3, 6], "unif": 6, "uniform": [3, 9, 10], "uniformcontinu": 9, "uniformcontinuous_iff": 9, "uniformli": 10, "union": [1, 3, 4, 5, 6, 7, 8, 10, 11], "union_def": 3, "uniqu": [1, 2, 3, 4, 5, 7, 8, 9], "unit": [5, 6, 9], "units_eq_one_or": 7, "univ": [3, 9, 10, 11], "univ_set": 9, "univari": 7, "univers": [1, 3, 5, 7, 8, 9, 13], "unknown": 6, "unless": [1, 2, 5], "unlik": [3, 4], "unnecessari": [3, 7], "unneed": 8, "unpack": [2, 3], "unpleas": [6, 9], "unrel": 6, "unshad": 3, "unspecifi": [6, 8], "unsurprisingli": 3, "until": [1, 4, 6, 9], "up": [0, 2, 3, 4, 5, 6, 7, 9], "updat": 0, "upper": [1, 2], "us": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13], "usabl": 6, "usag": 1, "useless": 8, "user": [0, 6], "usual": [1, 2, 3, 4, 5, 7, 8, 9, 11], "v": [0, 1, 2, 3, 5, 8, 9], "val": 5, "valid": 2, "valu": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "van": 0, "vandermond": 8, "vanish": [7, 8], "varepsilon": [2, 9], "variabl": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "variant": [1, 2, 7, 9], "variat": [1, 3, 4, 5, 9, 10], "varieti": 9, "variou": [2, 3, 5, 6, 8, 11], "vastli": 2, "ve": [6, 9], "vecmul": 8, "vector": [1, 3, 6, 7, 10, 13], "verbatim": 7, "verbos": 3, "veri": [0, 2, 4, 6, 7, 8, 9, 11], "verifi": 2, "versa": [1, 3], "version": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "vertic": [2, 5, 8], "vi": 5, "via": 9, "vice": [1, 3], "victor": 0, "view": [5, 6, 7, 9], "virtual": 8, "visibl": 1, "vocabulari": [3, 8], "volum": 11, "w": [1, 6, 8], "wa": [1, 3, 7], "wai": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11], "want": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "wasn": 9, "we": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "weak": 6, "weaker": [1, 2], "weav": 5, "web": [0, 1, 4], "weight": 5, "weightedaverag": 5, "weird": [6, 9], "weirder": 10, "welcom": [0, 1], "well": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "were": [2, 4, 5, 8, 9], "what": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], "whatev": [0, 2, 4], "whatsnew": 6, "when": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "whenev": [1, 2, 4, 5, 8], "where": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "wherea": [0, 1, 2, 3, 5, 7, 9], "wherebi": [5, 9], "whether": [2, 3, 4, 6, 9], "which": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "while": [0, 1, 2, 6, 7, 8, 9], "who": [0, 9], "whole": [5, 8], "whose": [1, 2, 4, 5, 6, 7, 8, 9, 10], "why": [0, 2, 4, 6, 7, 8, 9], "wieser": 0, "window": [0, 1, 2, 5], "winston": 0, "wise": [5, 8], "wish": 9, "withbot": 7, "within": [1, 2, 9], "without": [1, 2, 4, 5, 6, 7, 8, 9, 10], "withtop": 10, "wlog": 3, "won": [2, 4, 6, 7, 9], "wonder": 8, "word": [1, 2, 3, 4, 5, 7, 8, 9], "work": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "world": 0, "worri": [1, 3, 4, 5, 7], "worth": [1, 2, 5], "would": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "wouldn": 6, "wrap": [6, 9], "write": [0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11], "written": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "wrong": 3, "wrote": 4, "x": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "x_0": 9, "x_1": [2, 3], "x_2": [2, 3], "x_i": 9, "x_nonneg": 5, "xa": 3, "xai": 3, "xeq": [2, 3], "xgt": 2, "xlt": 2, "xltz": 2, "xmem": 3, "xnt": 3, "xnu": 3, "xpo": 3, "xstu": 3, "xsu": 3, "xt": 3, "xtu": 3, "xu": 3, "xy": [2, 5], "x\u2080": [9, 10], "x\u2081": [2, 3, 5, 9], "x\u2081a": 3, "x\u2082": [2, 3, 5], "x\u2082a": 3, "x\u2082eq": 3, "x\u2082na": 3, "y": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "y_nonneg": 5, "yannick": 0, "yball": 9, "yeq": 2, "yet": [2, 3, 4, 5, 6, 8, 9], "yield": [1, 2, 3, 4, 5, 9], "ylim": 9, "ylt": 2, "you": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "your": [0, 1, 2, 3, 5, 6, 7, 9], "yourself": [2, 5], "ypo": 3, "y\u2080": 9, "y\u2081": 5, "y\u2082": 5, "z": [0, 1, 2, 5, 6, 7, 8, 9, 10, 11], "z_nonneg": 5, "zermelo": 2, "zero": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "zero_add": [1, 4, 5, 6], "zero_def": 5, "zero_dvd_iff": 4, "zero_im": 5, "zero_l": [4, 5], "zero_lt_on": [2, 4], "zero_lt_two": 5, "zero_mem": [7, 8], "zero_mul": [1, 4, 5, 6], "zero_r": 5, "zero_smul": 6, "zeroth": 8, "zf": 2, "zlty": 2, "zmod": 7, "zsmul": [5, 6], "zsmulrec": 5, "zsmul\u2081": 6, "zulip": [0, 4], "z\u2080": 9, "z\u2081": 5, "z\u2082": 5, "\u00b9": [1, 3, 5, 6, 7, 8, 9], "\u02e2": 9, "\u03b1": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "\u03b2": [1, 2, 3, 5, 6, 8, 9, 11], "\u03b3": [1, 2, 5, 9], "\u03b4": [2, 9], "\u03b4po": 9, "\u03b5": [2, 9, 10], "\u03b52po": 2, "\u03b5_po": [9, 10], "\u03b5k_po": 10, "\u03b5po": [2, 9], "\u03b8": 8, "\u03b9": [7, 8, 9, 10, 11], "\u03bc": [9, 11], "\u03bd": 11, "\u03c0": [7, 8, 9, 10], "\u03c3": [5, 7], "\u03c6": [7, 8, 9], "\u03c8": [7, 8], "\u03c9": 7, "\u1d40": 8, "\u1d50": 11, "\u1d65": [7, 8], "\u1d9c": 7, "\u1da0": [9, 10, 11], "\u2080": [3, 8], "\u2081": 6, "\u2090": 7, "\u2097": 8, "\u2102": [1, 5, 7, 8, 10], "\u2115": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "\u211a": [1, 4, 7, 8, 9], "\u211d": [1, 2, 3, 5, 6, 7, 8, 9, 10, 11], "\u2124": [1, 4, 5, 6, 7, 8], "\u2124\u02e3": 7, "\ud835\udcdd": [9, 10, 11], "\ud835\udcdf": 9, "\ud835\udce4": 9, "\ud835\udd42": 10, "\ud835\udd5c": [10, 11], "\ud835\udfd9": 6}, "titles": ["<span class=\"section-number\">1. </span>Introduction", "<span class=\"section-number\">2. </span>Basics", "<span class=\"section-number\">3. </span>Logic", "<span class=\"section-number\">4. </span>Sets and Functions", "<span class=\"section-number\">5. </span>Elementary Number Theory", "<span class=\"section-number\">6. </span>Structures", "<span class=\"section-number\">7. </span>Hierarchies", "<span class=\"section-number\">8. </span>Groups and Rings", "<span class=\"section-number\">9. </span>Linear algebra", "<span class=\"section-number\">10. </span>Topology", "<span class=\"section-number\">11. </span>Differential Calculus", "<span class=\"section-number\">12. </span>Integration and Measure Theory", "Index", "Mathematics in Lean"], "titleterms": {"The": [2, 3], "about": 1, "action": 7, "algebra": [1, 5, 7, 8], "appli": 1, "asymptot": 10, "ball": 9, "base": 8, "basic": [1, 6], "bernstein": 3, "build": 5, "calcul": 1, "calculu": 10, "close": 9, "compact": 9, "comparison": 10, "complet": [8, 9], "concret": 7, "conjunct": 2, "continu": [9, 10], "converg": [2, 9], "countabl": 9, "defin": 5, "differenti": 10, "dimens": 8, "direct": 8, "disjunct": 2, "elementari": [4, 10, 11], "endomorph": 8, "exampl": 1, "existenti": 2, "fact": 1, "filter": 9, "function": [3, 9], "fundament": 9, "gaussian": 5, "get": 0, "group": 7, "hierarchi": 6, "ideal": 7, "ident": 1, "iff": 2, "implic": 2, "index": 12, "induct": 4, "infinit": 4, "integ": 5, "integr": 11, "intern": 8, "introduct": 0, "irrat": 4, "lattic": 8, "lean": 13, "lemma": 1, "linear": [8, 10], "logic": 2, "mani": 4, "map": [8, 10], "mathemat": 13, "matric": 8, "measur": 11, "metric": 9, "monoid": 7, "more": 1, "morphism": [6, 7], "negat": 2, "norm": 10, "number": 4, "object": 6, "open": 9, "overview": 0, "polynomi": 7, "prime": 4, "product": 8, "prove": 1, "pull": 8, "push": 8, "quantifi": 2, "quotient": [7, 8], "recurs": 4, "ring": 7, "root": 4, "rw": 1, "schr\u00f6der": 3, "separ": 9, "sequenc": 2, "set": [3, 8, 9], "space": [8, 9, 10], "span": 8, "start": 0, "structur": [1, 5, 8], "sub": 6, "subgroup": 7, "subr": 7, "subspac": 8, "sum": 8, "theorem": [1, 3], "theori": [4, 11], "topolog": 9, "topologi": 9, "uniformli": 9, "unit": 7, "univers": 2, "us": 1, "vector": 8}})
-
-