Liam's bloghttps://tybug.dev/2026-02-11T00:00:00-05:00Property-based testing is about to rule the (software) world2026-02-11T00:00:00-05:002026-02-11T00:00:00-05:00tag:tybug.dev,2026-02-11:/specs<p><em>And what can we do to prepare?</em></p>
<p>Many people have strong opinions about the next few years of AI progress. Regardless of yours, I claim that (1) the models will continue to improve for at least another 6 months; and (2) even if that stopped <em>today</em>, Opus 4.6-tier models …</p><p><em>And what can we do to prepare?</em></p>
<p>Many people have strong opinions about the next few years of AI progress. Regardless of yours, I claim that (1) the models will continue to improve for at least another 6 months; and (2) even if that stopped <em>today</em>, Opus 4.6-tier models are already powerful enough to dramatically change how many developers write software.</p>
<p>I characterize this change as "AI code is treated as a black box". AI-pilled programmers care only about the observable outcome of code, not the implementation. In other words: the only thing that matters anymore <em>is the guarantees on the box</em>. When I ask the black-box z3 solver for a satisfying assignment, I don't care how it got there, only that the result is a valid SAT formula.</p>
<p>If we are to embrace AI code as an industry, we will and must adopt better ways to place guarantees on these black boxes. And I think property-based testing will quickly emerge as the forerunner.<sup id="fnref:2"><a class="footnote-ref" href="proxy.php?url=#fn:2">1</a></sup><sup id="fnref:3"><a class="footnote-ref" href="proxy.php?url=#fn:3">2</a></sup></p>
<h1>Property-based testing</h1>
<p>I have always been surprised at how under-adopted property-based testing is. Do companies not care about testing? Is it not mentioned enough in university curriculums? (Yes, but I digress). Has PBT just not permeated the cultural zeitgeist?</p>
<p>It doesn't really matter. AI is about to provide the forcing function for PBT to become a developer household name. Or, to put it another way: <em>PBT is about to get a lot more users</em>.</p>
<p>And yet, the PBT ecosystem is underprepared for this influx. In Python, I maintain <a href="proxy.php?url=https://github.com/hypothesisWorks/hypothesis">Hypothesis</a>, which I have no qualms in claiming as the most successful PBT library of all time.<sup id="fnref:1"><a class="footnote-ref" href="proxy.php?url=#fn:1">3</a></sup> Python might well weather this storm.</p>
<p>But as much as I love Python, it comprises a small percentage of production code. What about other languages? Most do have a PBT library. And, to be clear, many years of development effort have gone into them. But I think even their maintainers will acknowledge most other libraries don't match the breadth and depth of Hypothesis:</p>
<ul>
<li><a href="proxy.php?url=https://drmaciver.github.io/papers/reduction-via-generation-preview.pdf">Internal shrinking</a>, which is <a href="proxy.php?url=https://github.com/jlink/shrinking-challenge">consistently world-class</a></li>
<li><a href="proxy.php?url=https://hypothesis.readthedocs.io/en/latest/extensions.html#alternative-backends">Pluggable backends</a>, including <a href="proxy.php?url=https://github.com/pschanely/hypothesis-crosshair">z3 integration</a></li>
<li><a href="proxy.php?url=https://hypothesis.readthedocs.io/en/latest/reference/integrations.html#observability">Observability</a></li>
<li><a href="proxy.php?url=https://hypofuzz.com/">Coverage-guided fuzzing integration</a></li>
<li><a href="proxy.php?url=https://github.com/HypothesisWorks/hypothesis/issues/3921">A powerful internal test case representation</a></li>
<li><a href="proxy.php?url=https://hypothesis.readthedocs.io/en/latest/stateful.html">Stateful testing</a></li>
<li><a href="proxy.php?url=https://hypothesis.readthedocs.io/en/latest/tutorial/replaying-failures.html">Test case database</a>, for regressions</li>
<li>Test case deduplication</li>
</ul>
<p>My point is not to glorify Hypothesis. Even after 11 years of development, there is always more to improve. Rather, the demand for PBT is about to explode, and I don't think any language is prepared for it—maybe not even Python.</p>
<p>My concrete call to action: as a PBT ecosystem, we need to figure out how to share improvements among all libraries, to consolidate and amplify the best of our development effort. I am not the first to say this, but it has never been more true than today. The open <a href="proxy.php?url=https://hypothesis.readthedocs.io/en/latest/reference/integrations.html#observability">PBT observability spec</a> is designed for any language and is a step in this direction.</p>
<p>What else can we standardize? Shrinking? The database? The choice sequence? How can we take the best parts of <em>every</em> library and combine them into one, in preparation for the PBT renaissance?</p>
<p>If you maintain a PBT library and want to collaborate with Hypothesis on this, <a href="proxy.php?url=mailto:[email protected]">reach out</a>.</p>
<div class="footnote">
<hr>
<ol>
<li id="fn:2">
<p>At least until we can autonomously formally verify code according to the theorem statement "this code has no bugs". I expect this to be many years away even at current model progress rates. <a class="footnote-backref" href="proxy.php?url=#fnref:2" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li id="fn:3">
<p>Or fuzzing, if you prefer that framing. I largely see fuzzing and PBT as two views on the identical problem, and think it's unfortunate we don't have more communication between these two worlds. <a class="footnote-backref" href="proxy.php?url=#fnref:3" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
<li id="fn:1">
<p>See <a href="proxy.php?url=https://hypothesis.readthedocs.io/en/latest/usage.html">https://hypothesis.readthedocs.io/en/latest/usage.html</a>. For example, <a href="proxy.php?url=https://lp.jetbrains.com/python-developers-survey-2024/">4% of 2024 PSF survey respondents report using Hypothesis</a>. <a class="footnote-backref" href="proxy.php?url=#fnref:1" title="Jump back to footnote 3 in the text">↩</a></p>
</li>
</ol>
</div>homebrew catan2024-08-27T00:00:00-04:002024-08-27T00:00:00-04:00tag:tybug.dev,2024-08-27:/homebrew-catan<p>My family's board game of choice is Catan. We've probably played close to 50 games of it in my lifetime. We've experimented with some small homebrew rules before, and more recently I saw <a href="proxy.php?url=https://robert.ocallahan.org/2024/06/real-time-settlers.html">real-time Catan</a>, which we played two games of. Even after two games it was clear to us …</p><p>My family's board game of choice is Catan. We've probably played close to 50 games of it in my lifetime. We've experimented with some small homebrew rules before, and more recently I saw <a href="proxy.php?url=https://robert.ocallahan.org/2024/06/real-time-settlers.html">real-time Catan</a>, which we played two games of. Even after two games it was clear to us that real-time Catan is an enormous improvement, and I doubt we'll ever go back to regular Catan again.</p>
<p>That said, we did find we needed to tweak the rules. Here's our full homebrew ruleset, building off cities and knights + seafarers:</p>
<ul>
<li>Turns have a set time limit. We generally start with 45 seconds a turn, and increase to 60 seconds later in the game if it's clear people need more time for more complex turns.</li>
<li>You may take any action on anybody's turn, including trading with anyone else.</li>
<li>The only exception to this is progress cards, which must be played on your turn.</li>
<li>When a player takes an action that requires a response from another player (e.g. master merchant), pause the timer for all players.</li>
<li>When a player reaches 13 victory points, the game does not end immediately. Instead there is an (indefinite, but reasonable) rebuttal period for the remainder of the turn where players continue to play.</li>
<li>If a player still has 13 VPs at the end of the turn, they win.</li>
<li>If two players are tied for VPs at the end of the turn, play continues until one player is ahead at the end of a turn.</li>
<li>If any actions conflict, ties are broken by turn order, with the person who's turn it is having priority, and so on continuing clockwise.</li>
<li>You may declare any progress card you own as tradeable by placing it face up in front of you.</li>
<li>You can barter with other players using tradeable progress cards as you would any other resource.</li>
<li>They are still progress cards in every respect. They count toward your progress card limit, they can be stolen by the spy, and you can still play them.</li>
</ul>
<p>All other rules that interact with turns are still in play: you cannot play a progress card on the same turn you recieve it, the player who rolls a 7 moves the robber, etc. The purpose of the rebuttal period is to deter players from waiting until the last second to reach 13 victory points. And the purpose of not immediately ending the game when a player "wins" is to avoid a mad rush to reach 13 victory points before anyone else on a turn! Requiring progress cards to be played on your turn is both to nerf them, as we found they were otherwise too powerful, and to reduce the potential for conflicting actions.</p>
<p>In my opinion, breaking ties by turn order is more elegant than casually deciding each case at the table, as the original post described. We found conflicting actions to be a large problem – they only happened ~once a game, but could turn the course of the game (such as a wedding played right as someone builds a settlement).</p>
<p>While we're on the topic of homebrews, we've long been searching for a way to make the green commodity's ability in cities and knights less powerful, but haven't found anything thematically satisfying while not nerfing it into the ground.</p>
<p>Thanks to Robert O'Callahan for describing the original idea!</p>git as a backup system2022-08-23T00:00:00-04:002022-08-23T00:00:00-04:00tag:tybug.dev,2022-08-23:/git-as-a-backup-system<p>For the past few months I've been using git as my backup system for my mac. I'm only backing up my own files (music, code, etc) and not software or system files, so it's not intended to be a drop-in replacement for setting up a new machine.</p>
<h1>Pros / Cons</h1>
<p>There's …</p><p>For the past few months I've been using git as my backup system for my mac. I'm only backing up my own files (music, code, etc) and not software or system files, so it's not intended to be a drop-in replacement for setting up a new machine.</p>
<h1>Pros / Cons</h1>
<p>There's some obvious reasons why you shouldn't do this:</p>
<ul>
<li>git can't preserve advanced file permissions like access control list (but does preserve basic rwx file modes)</li>
<li>git can't commit empty folders</li>
<li>git wasn't designed to be a backup system (less of a strict negative and more of an icky feeling)</li>
<li>git has trouble dealing with nested repositories</li>
<li>git has no builtin backup commands (like "restore this file as of 1 week and 2 days ago")</li>
</ul>
<p>That said, there are some pros:</p>
<ul>
<li>you don't have to learn the syntax of a separate backup system</li>
<li>very low chance of your backup system (git) becoming unmaintained in the future</li>
<li>differential backups for free</li>
</ul>
<p>The first few negatives I listed aren't a big deal for me. I'm the only one who uses my computer, so I don't need to wory about ACL, and all the files I'm backing up are owned by me, so I don't even really need to worry about storing file ownership. Not preserving empty folders is unfortunate, but the number of empty folders I care about on my computer right now is probably less than 2, so I'm ok with letting that go.</p>
<p>The others are more problematic. Git's solution to nested repositories is submodules, which is an entire layer of complication I didn't want to deal with. I think it's easier to simply remove all nested git repositories from your backup before committing. When I say remove, I just mean renaming any <code>.git</code> folders to something else - like <code>._git</code> - so git doesn't think it's a repository. It'll just track changes to it like any normal file. Then when you want to restore from a backup, you can rename any <code>._git</code> folders to <code>.git</code> again.</p>
<p>This approach isn't perfect: it effectively means I can't name a folder <code>._git</code>. I can't imagine why I would, so I'm fine with this. And if I ever do, I could always change my backups to use <code>.git_backup_very_unique_string</code> or something instead.</p>
<h1>Taking Backups</h1>
<p>My workflow for backing up looks something like this:</p>
<ul>
<li>connect my external harddrive to my mac</li>
<li>copy the files I want to back up to the external harddrive. Right now I back up the entirety of <code>~/Desktop</code>, as well as some select files from my <code>~/</code></li>
<li>rename all <code>.git</code> directories to <code>._git</code>, and do the same for any special git files (eg <code>.gitignore</code>)</li>
<li>delete everything that was previously in my backup directory on my external harddrive, except the master <code>.git</code> repository</li>
<li>copy over the new directory into the backup directory</li>
<li>run <code>git add . && git commit -a -m "backup mm/dd/yyy"</code>, replacing with current date</li>
</ul>
<p>You have to delete the previous backup before replacing it. Otherwise, files which were deleted won't be removed, and git won't think they got deleted.</p>
<p>I wrote <a href="proxy.php?url=https://github.com/liam-devoe/dotfiles/blob/87e966b263b62c88b9986d92800b6ff1e2303473/bin/backup">a script</a> which automates steps 3+, so I just have to copy the files I want to back up to <code>/Volumes/Backup/temporary</code> and run <code>cd /Volumes/Backup/computer\ backups/tybug && backup /Volumes/Backup/temporary</code>, where <code>Backup</code> is the name of my external harddrive.</p>
<p>I could automate this further, but I don't see the point since I have to manually connect my external harddrive anyway.</p>
<h1>Is it any good?</h1>
<p>Sort of.</p>
<p>The good news is, it totally works. I want to see how my harddrive looked last year? <code>git checkout 4458befdb9</code>, where <code>4458befdb9</code> was my backup on <code>06/01/2021</code>. I want to see what changed since the last backup in a particular directory? <code>git diff HEAD^ -- Desktop/Liam/Music/Various\ Artists/AD:TRANCE\ 2</code>.</p>
<p>It's slightly harder to restore a single directory to a previous backup. You have to do something like this:</p>
<div class="highlight"><pre><span></span><code><span class="c1"># https://stackoverflow.com/a/42224112</span>
git<span class="w"> </span>reset<span class="w"> </span>HEAD^<span class="w"> </span>--<span class="w"> </span>dir
git<span class="w"> </span>checkout<span class="w"> </span>--<span class="w"> </span>dir
git<span class="w"> </span>clean<span class="w"> </span>-fd<span class="w"> </span>--<span class="w"> </span>dir
</code></pre></div>
<p>But it's not too bad to just stick those three lines into a script. The reason this is necessary is that in git, resetting to a previous commit doesn't clean your working tree from any files that don't exist in that commit. Usually, this is what we want, but since this is a backup we know for a fact there are no stray files and can <code>git clean</code> them away.</p>
<p>The biggest downside, though, is that things are just <em>slow</em>.</p>
<p>For instance, it takes 20 minutes to clean the backup directory and copy the new backup over from its temporary location to the backup directory. Then <code>git add .</code> takes around 10 minutes and <code>git commit -a -m "mm/dd/yyyy"</code> takes around 30 minutes. All timings taken from a 140gb backup (with only 20gb of differential changes from the previous backup) on my 14 inch 2021 macbook pro, copying to a 1TB ssd.</p>
<p>In other words, it takes around an hour to take a backup, from start to finish. I can live with this: the entirety of that time is spent in a script, so I can leave it running and forget about it.</p>
<p>The bigger problem is that git itself is slow for large repositories. On my current backup repository (190gb .git folder, 140gb working tree), running <code>git checkout HEAD^</code> takes 20 minutes. Even running <code>git status</code> took 10 minutes until I enabled git's <code>manyFiles</code> flag with <code>git config --global feature.manyFiles true</code>. That took it down to 5 seconds most of the time, except when it needs to update caches, which can take 10 minutes again. The cache seems to get invalidated whenever you check out another backup, so it's not that useful. At least running multiple <code>git status</code> commands without checking out is much faster with this option enabled.</p>
<p>Git will also decide it needs to garbage collect every third backup or so. This is good - presumably git knows better than I do when things are getting fragmented and need to be repacked - but when it happens it adds even more running time (about 15 minutes) to an already long operation.</p>
<h1>Final Thoughts</h1>
<p>Do I regret using git as my backup system? Not really, but I wouldn't recommend it to anyone else. I'm only okay with the slow speeds because I will very rarely need to checkout older backups or compare diffs. Or if I do, I'm fine with dumping the diff to a file (and paying an initial cost of 20 minutes for that to complete) and then examining it outside of git with no additional penalty.</p>
<p>To me, the convenience of familiar syntax and longevity assurance is worth it, but I don't think that would be true for most people. Use an actual backup system designed for backups instead of trying to hammer git into a backup-shaped hole.</p>gödel's incompleteness theorem2022-03-16T00:00:00-04:002022-03-16T00:00:00-04:00tag:tybug.dev,2022-03-16:/incompleteness<p>Ah, Gödel's incompleteness theorem. I won't say it's the most misused theorem in all of mathematics, but I would argue it has the worst ratio of "people who actually understand it" to "people who misapply it".</p>
<p>Here it is:</p>
<div class="quote">For any sufficiently strong theory $T$, there is a sentence $\sigma …</div><p>Ah, Gödel's incompleteness theorem. I won't say it's the most misused theorem in all of mathematics, but I would argue it has the worst ratio of "people who actually understand it" to "people who misapply it".</p>
<p>Here it is:</p>
<div class="quote">For any sufficiently strong theory $T$, there is a sentence $\sigma$ which is independent of $T$.</div>
<p>Before we can unpack it, you need a crash course in model theory. This will be a little bit painful, but I promise it's critically important.</p>
<h1>Sentences and Theories</h1>
<p>Here are the axioms of group theory, which you'll find at the beginning of any standard textbook:</p>
<div class="arithmatex">\[
\begin{equation}
\begin{aligned}
& \sigma_0: \forall a \forall b \forall c \ (c*(a*b) = (c*a)*b) \\
& \sigma_1: \forall a \ (e*a = a) \\
& \sigma_2: \forall a \exists b \ (a*b = e) \\
\end{aligned}
\end{equation}
\]</div>
<p>(If you're not familiar with group theory, don't worry; the actual content of these axioms is largely irrelevant for us. They state that <span class="arithmatex">\(*\)</span> is associative, has an identity <span class="arithmatex">\(e\)</span>, and every element has an inverse respectively).</p>
<p>What your group theory textbook probably didn't tell you is that there's a language <span class="arithmatex">\(L_{group}\)</span> associated with group theory. This is the set of special symbols we'd like to be able to refer to in our sentences: <span class="arithmatex">\(L_{group} = \{e, *\}\)</span>.</p>
<p>The three axioms above are examples of sentences. A <strong>sentence</strong> is a statement in first order logic which contains only logical symbols (<span class="arithmatex">\(\lnot\)</span>, <span class="arithmatex">\(\land\)</span>, <span class="arithmatex">\(\lor\)</span>, <span class="arithmatex">\(\implies\)</span>, <span class="arithmatex">\(\iff\)</span>, <span class="arithmatex">\(\forall\)</span>, <span class="arithmatex">\(\exists\)</span>), or symbols from our language <span class="arithmatex">\(L\)</span>. For instance, the following is not an <span class="arithmatex">\(L_{group}\)</span>-sentence:</p>
<div class="arithmatex">\[\forall a \ (a + a = a)\]</div>
<p>because <span class="arithmatex">\(+\)</span> isn't in <span class="arithmatex">\(L_{group}\)</span>. Note that whether a statement is a sentence or not depends on the language, which is why we say <span class="arithmatex">\(L_{group}\)</span>-sentence instead of just sentence. When the language is clear from context, we'll drop the <span class="arithmatex">\(L\)</span>- prefix and call it a sentence.</p>
<p>We can bundle these axioms together into an object called a <strong>theory</strong>. <span class="arithmatex">\(T_{group} = \{\sigma_0, \sigma_1, \sigma_2\}\)</span> is the theory of groups. A theory is any set of sentences.<sup id="fnref:1"><a class="footnote-ref" href="proxy.php?url=#fn:1">1</a></sup></p>
<p>Here's the incompleteness theorem again:</p>
<div class="quote">For any sufficiently strong theory $T$, there is a sentence $\sigma$ which is independent of $T$.</div>
<p>We've defined <strong>sentence</strong> and <strong>theory</strong>. Let's tackle <strong>independent</strong> next.</p>
<h1>Models</h1>
<p>To discuss independence of sentences, we first need to talk about models. We say that <span class="arithmatex">\(\mathcal{A}\)</span> is a model of a theory <span class="arithmatex">\(T\)</span> if <span class="arithmatex">\(\sigma\)</span> is true in <span class="arithmatex">\(\mathcal{A}\)</span> for all <span class="arithmatex">\(\sigma \in T\)</span>.<sup id="fnref:2"><a class="footnote-ref" href="proxy.php?url=#fn:2">2</a></sup></p>
<p>Don't be scared by the notation. If you wanted to check whether something is a group or not, what do you do? You check that it satisfies all the axioms of being a group. That's all this definition is stating. Saying "<span class="arithmatex">\((\mathbb{Z}, +)\)</span> is a group" is equivalent to saying "<span class="arithmatex">\((\mathbb{Z}, +)\)</span> models <span class="arithmatex">\(T_{group}\)</span>". And if <span class="arithmatex">\(\mathcal{A}\)</span> models <span class="arithmatex">\(T\)</span>, we write <span class="arithmatex">\(\mathcal{A} \vDash T\)</span>.</p>
<p>We need just one more definition. Let <span class="arithmatex">\(T\)</span> be any theory. Then <span class="arithmatex">\(T\)</span> is <strong>complete</strong> if, for all sentences <span class="arithmatex">\(\sigma\)</span> and for all models <span class="arithmatex">\(\mathcal{A} \vDash T\)</span> and <span class="arithmatex">\(\mathcal{B} \vDash T\)</span>, <span class="arithmatex">\(\sigma\)</span> is true in <span class="arithmatex">\(\mathcal{A}\)</span> iff <span class="arithmatex">\(\sigma\)</span> is true in <span class="arithmatex">\(\mathcal{B}\)</span>. In other words, "every model of <span class="arithmatex">\(T\)</span> agrees on the truth value of every sentence".</p>
<p>A natural question is whether <span class="arithmatex">\(T_{group}\)</span> is complete. Can you think of a sentence <span class="arithmatex">\(\sigma\)</span> which is true in some group <span class="arithmatex">\(\mathcal{A} \vDash T_{group}\)</span> but false in another group <span class="arithmatex">\(\mathcal{B} \vDash T_{group}\)</span>? Hint: the answer is yes, there are several such sentences, and they aren't that complicated. Try and think of one now before you read on, if you like.</p>
<p>(pause...) if you said "<span class="arithmatex">\(\mathcal{A}\)</span> is abelian" (ie <span class="arithmatex">\(*\)</span> commutes in <span class="arithmatex">\(\mathcal{A}\)</span>), you're correct! I also would have accepted "<span class="arithmatex">\(\mathcal{A}\)</span> has an element of order n" for some n. Here's a sentence that is true in <span class="arithmatex">\(\mathcal{A}\)</span> iff <span class="arithmatex">\(\mathcal{A}\)</span> is abelian:</p>
<div class="arithmatex">\[
\sigma_{abelian} = \forall a \forall b \ (a*b = b*a)
\]</div>
<p>To see that <span class="arithmatex">\(\sigma_{abelian}\)</span> proves that <span class="arithmatex">\(T_{group}\)</span> is not complete, pick your favorite abelian group, say <span class="arithmatex">\((\mathbb{Z}, +)\)</span>, and your favorite non-abelian group, say <span class="arithmatex">\(GL(2, \mathbb{R})\)</span>. <span class="arithmatex">\(\sigma_{abelian}\)</span> is true in <span class="arithmatex">\((\mathbb{Z}, +)\)</span> and false in <span class="arithmatex">\(GL(2, \mathbb{R})\)</span>, since addition commutes and matrix multiplication does not. But both <span class="arithmatex">\((\mathbb{Z}, +)\)</span> and <span class="arithmatex">\(GL(2, \mathbb{R})\)</span> are models of <span class="arithmatex">\(T_{group}\)</span> — after all, they're both groups and thus satisfy the three axioms of <span class="arithmatex">\(T_{group}\)</span>. So <span class="arithmatex">\(\sigma_{abelian}\)</span> is true in <span class="arithmatex">\((\mathbb{Z}, +) \vDash T_{group}\)</span> and false in <span class="arithmatex">\(GL(2, \mathbb{R}) \vDash T_{group}\)</span>, so <span class="arithmatex">\(T_{group}\)</span> is not complete.</p>
<h1>Independence</h1>
<p>What about independence? Let <span class="arithmatex">\(T\)</span> be any theory and <span class="arithmatex">\(\sigma\)</span> be any sentence. Then <span class="arithmatex">\(\sigma\)</span> is <strong>independent</strong> of <span class="arithmatex">\(T\)</span> if there are two models <span class="arithmatex">\(\mathcal{A} \vDash T\)</span> and <span class="arithmatex">\(\mathcal{B} \vDash T\)</span> such that <span class="arithmatex">\(\sigma\)</span> is true in <span class="arithmatex">\(\mathcal{A}\)</span> and false in <span class="arithmatex">\(\mathcal{B}\)</span>. In the example above, <span class="arithmatex">\(\sigma_{abelian}\)</span> is independent of <span class="arithmatex">\(T_{group}\)</span>. A corollary is that a theory <span class="arithmatex">\(T\)</span> is not complete iff there is some sentence <span class="arithmatex">\(\sigma\)</span> which is independent of <span class="arithmatex">\(T\)</span>. I'll do the proof explicitly below, but it's nothing more than unpacking the respective definitions.</p>
<div class="quote">
$\implies$ Let $T$ be not complete. So there is some sentence $\sigma$, some model $\mathcal{A} \vDash T$ and $\mathcal{B} \vDash T$, such that either $\sigma$ is true in $\mathcal{A}$ and false in $\mathcal{B}$, or false in $\mathcal{A}$ and true in $\mathcal{B}$. In either case, $\sigma$ is independent.
</div>
<div class="quote">
$\impliedby$ Let $\sigma$ be a sentence independent of $T$. Then there are $\mathcal{A} \vDash T$ and $\mathcal{B} \vDash T$ such that $\sigma$ is true in $\mathcal{A}$ and false in $\mathcal{B}$. So $T$ is not complete. $\blacksquare$
</div>
<p>If a theory <span class="arithmatex">\(T\)</span> is "not complete", we call <span class="arithmatex">\(T\)</span> incomplete.</p>
<p>Let's take a closer look at the incompleteness theorem, as stated:</p>
<div class="quote">For any sufficiently strong theory $T$, there is a sentence $\sigma$ which is independent of $T$.</div>
<p>We just proved that <span class="arithmatex">\(T\)</span> is incomplete iff there is a sentence <span class="arithmatex">\(\sigma\)</span> which is independent of <span class="arithmatex">\(T\)</span>. So we can restate the theorem as:</p>
<div class="quote">Any sufficiently strong theory $T$ is incomplete.</div>
<p>This is where the "incompleteness" portion of the theorem's name comes from. Although these statements are equivalent, I'll continue to use the first, longer version, since I feel it's more intuitive (as it doesn't require you to unpack the definition of <span class="arithmatex">\(T\)</span> being incomplete).</p>
<p>Before I make our final definition of <strong>sufficiently strong</strong>, I want to take a detour into euclidean geometry as a final example to round out our discussion of theories and models.</p>
<h1>Euclidean geometry</h1>
<p>Euclidean geometry is another example of a theory. It contains five axioms and three "undefined terms": point, line, and plane are undefined and are referenced in the axioms without definition. Does that sound familiar? We did the exact same thing in groups, using the "undefined terms" <span class="arithmatex">\(*\)</span> and <span class="arithmatex">\(e\)</span> in our axioms, and defining them to be part of our language <span class="arithmatex">\(L_{group}\)</span>. It turns out that the notion of a language has always been hiding in euclidean geometry. The language of euclidean geometry is just <span class="arithmatex">\(L_{euclid} = \{\text{point}, \text{line}, \text{plane}\}\)</span>. I'll call <span class="arithmatex">\(T_{EG}\)</span> the theory of euclidean geometry, which is the set of the five axioms of euclidean geometry.</p>
<p>You'll notice that I'm not giving a precise mathematic definition of the axioms, but that's because Euclid himself didn't really give precise mathematical definitions either. Euclidean geometry can in fact be made precise (see <a href="proxy.php?url=https://en.wikipedia.org/wiki/Tarski%27s_axioms">Tarski's Axioms</a>), and everything I say below will still hold, but I'll avoid deviating too much from the euclidean geometry described in Euclid's Elements.</p>
<p>You may also know of the particularly contentious parallel postulate (PP), the fifth axiom of euclidean geometry. Some people thought that the parallel postulate could be proven from the rest of the axioms, and gave the name "neutral geometry" to the set of axioms of euclidean gemoetry without PP. I'll call the theory of neutral geometry <span class="arithmatex">\(T_{NG} = T_{EG} \setminus \{PP\}\)</span>. They then showed PP could not be proven from the rest of the axioms by constructucting two models of <span class="arithmatex">\(T_{NG}\)</span>: one in which PP was true (a model of euclidean geometry) and one in which PP is false (a model of elliptical geometry).</p>
<p>Once they had shown PP could not be proven from neutral geometry, they called PP independent of neutral geometry. Does this term "independent" sound familiar? It should — we defined <span class="arithmatex">\(\sigma\)</span> to be independent of <span class="arithmatex">\(T\)</span> if there are <span class="arithmatex">\(\mathcal{A} \vDash T\)</span>, <span class="arithmatex">\(\mathcal{B} \vDash T\)</span> where <span class="arithmatex">\(\sigma\)</span> is true in <span class="arithmatex">\(\mathcal{A}\)</span> and false in <span class="arithmatex">\(\mathcal{B}\)</span>. Here, <span class="arithmatex">\(\sigma\)</span> is the parallel postulate, <span class="arithmatex">\(T\)</span> is neutral geometry, <span class="arithmatex">\(\mathcal{A}\)</span> is a model of euclidean geometry, and <span class="arithmatex">\(\mathcal{B}\)</span> is a model of elliptical geometry. In general, proving that an axiom <span class="arithmatex">\(\sigma \in T\)</span> is "independent" of (cannot be proven from) the other axioms of <span class="arithmatex">\(T\)</span> is equivalent to proving that <span class="arithmatex">\(\sigma\)</span> is independent of <span class="arithmatex">\(T \setminus \{\sigma\}\)</span>, in the formal sense of independence described above.</p>
<p>Because PP is independent of <span class="arithmatex">\(T_{NG}\)</span>, <span class="arithmatex">\(T_{NG}\)</span> is incomplete. However, it turns out that <span class="arithmatex">\(T_{EG} = T_{NG} \cup \{\text{PP}\}\)</span> is complete, so by taking PP as a new axiom we've created a complete theory.<sup id="fnref:3"><a class="footnote-ref" href="proxy.php?url=#fn:3">3</a></sup> We'll discuss this concept of "completing" a theory <span class="arithmatex">\(T\)</span> by adding new axioms again later, and whether this can save us from the consequences of the incompleteness theorem. Spoiler: it can't.</p>
<h1>Sufficiently strong</h1>
<p>I've left the simplest – or at least, easiest to informally explain – for last. A theory <span class="arithmatex">\(T\)</span> is <strong>sufficiently strong</strong> if it contains the natural numbers, addition on the natural numbers, and multiplication on the natural numbers (or contains objects isomorphic to them). More formally, <span class="arithmatex">\(T\)</span> is sufficiently strong if it contains <a href="proxy.php?url=https://en.wikipedia.org/wiki/Robinson_arithmetic">Robinson arithmetic</a>, called <span class="arithmatex">\(Q\)</span>. If you're familiar with peano arithmetic, <span class="arithmatex">\(Q\)</span> is peano arithmetic without induction.</p>
<p>Understanding <em>why</em> containing <span class="arithmatex">\(Q\)</span> is necessary gets to the heart of the proof of the incompleteness theorem and is a much deeper discussion than we can get into here, so I hope you'll forgive me for not going into any more detail.</p>
<h1>Bringing it all together</h1>
<p>Let's recap:</p>
<ul>
<li>A sentence <span class="arithmatex">\(\sigma\)</span> is a statement in first order logic, potentially containing symbols from some language <span class="arithmatex">\(L\)</span></li>
<li>A theory <span class="arithmatex">\(T\)</span> is a set of sentences</li>
<li><span class="arithmatex">\(\mathcal{A}\)</span> is a model of <span class="arithmatex">\(T\)</span> (written <span class="arithmatex">\(\mathcal{A} \vDash T\)</span>) if <span class="arithmatex">\(\sigma\)</span> is true in <span class="arithmatex">\(\mathcal{A}\)</span> for all <span class="arithmatex">\(\sigma \in T\)</span></li>
<li>A sentence <span class="arithmatex">\(\sigma\)</span> is independent of a theory <span class="arithmatex">\(T\)</span> if there are models <span class="arithmatex">\(\mathcal{A} \vDash T\)</span>, <span class="arithmatex">\(\mathcal{B} \vDash T\)</span> with <span class="arithmatex">\(\sigma\)</span> true in <span class="arithmatex">\(\mathcal{A}\)</span> and false in <span class="arithmatex">\(\mathcal{B}\)</span></li>
<li>A theory <span class="arithmatex">\(T\)</span> is sufficiently strong if it contains <span class="arithmatex">\(Q\)</span>, aka robinson arithmetic (informally, if it contains the natural numbers, addition, and multiplication)</li>
</ul>
<p>And finally, the incompleteness theorem itself:</p>
<div class="quote">For any sufficiently strong theory $T$, there is a sentence $\sigma$ which is independent of $T$.</div>
<p>Congratulations — you now know everything you need to understand the statement of the incompleteness theorem. If that was your goal, you can walk away here, but I'll discuss the consequences of this theorem next.</p>
<h1>Consequences</h1>
<p>To start, a question: is the converse of the incompleteness theorem true? No. We saw above that <span class="arithmatex">\(T_{group}\)</span> has a sentence <span class="arithmatex">\(\sigma_{abelian}\)</span> which is independent of <span class="arithmatex">\(T_{group}\)</span>, but <span class="arithmatex">\(T_{group}\)</span> certainly does not contain <span class="arithmatex">\(Q\)</span>. Informally, this means that theories can be incomplete for "other reasons" than the incompleteness theorem (actually, it's quite easy to create incomplete theories; much easier than creating complete ones). The reason why the incompleteness theorem is so important is not because it applies to a large number of theories, but because the theories it does apply to are important ones that we would really prefer to be complete.</p>
<p>In particular, the incompleteness theorem often comes up adjacent to the foundations of mathematics, with theories like <span class="arithmatex">\(\text{ZFC}\)</span>. Although perhaps not obvious just by looking at the axioms, <span class="arithmatex">\(\text{ZFC}\)</span> can prove the axioms of <span class="arithmatex">\(Q\)</span>, and is in fact much, much stronger than it. So <span class="arithmatex">\(\text{ZFC}\)</span> is sufficiently strong and thus subject to the incompleteness theorem, so there is some <span class="arithmatex">\(\sigma\)</span> which is independent of <span class="arithmatex">\(\text{ZFC}\)</span>. In other words, there are theorems (sentences) which we will never be able to prove or disprove from the axioms of <span class="arithmatex">\(\text{ZFC}\)</span>.</p>
<p>This probably doesn't sound too bad. So what? Well, think about your favorite mathematical field (which almost certainly uses <span class="arithmatex">\(\text{ZFC}\)</span> as its mathemtical foundations, unless you're a category theorist). Then think about some famous unsolved conjecture in that field. Most people think there are only two options: either that conjecture is true, or it's false. The incompleteness theorem says there's a third possibility: the conjeture is one of these independent sentences <span class="arithmatex">\(\sigma\)</span>, and thus can never be proven or disproven in <span class="arithmatex">\(\text{ZFC}\)</span>.</p>
<p>I would say that proving a famous theorem independent is a much worse fate than proving it either true or false. Consider <span class="arithmatex">\(T_{NG}\)</span>, the theory of neutral geometry we discussed above, and the theorem under discussion to be the parallel postulate PP, which we know is independent of <span class="arithmatex">\(T_{NG}\)</span>. When PP was found to be independent of <span class="arithmatex">\(T_{NG}\)</span>, it split the world of euclidean geometry in two. In one camp are the worlds in which PP is true; we call these euclidean geometries, with theory <span class="arithmatex">\(T_{NG} \cup \{\text{PP}\}\)</span>. In the other camp are the worlds in which PP is false; we call these non-euclidean geometries, with theory <span class="arithmatex">\(T_{NG} \cup \{\lnot \text{PP}\}\)</span>. Because PP is independent of <span class="arithmatex">\(T_{NG}\)</span>, both of these worlds are "equally valid". In my opinion, having two possible worlds is worse than knowing for certain which "world" we live in, like we would if PP was not independent of <span class="arithmatex">\(T_{NG}\)</span> (and therefore either true or false).</p>
<p>However, there's a reason why non-euclidean geometries are significantly less studied: most people believe PP is "intuitively true", and study euclidean geometry instead of non-euclidean geometry. This is true of PP, but it's not true of all independent sentences. Sometimes an independent sentence really does fracture a theory into multiple, equally popular camps. In other words, it's not always obvious which "choice" to make (eg whether to add PP or <span class="arithmatex">\(\lnot\)</span>PP).</p>
<p>For instance, in set theory, the <a href="proxy.php?url=https://en.wikipedia.org/wiki/Continuum_hypothesis">Continuum Hypothesis</a> (CH) is the most well known example of a theorem independent of <span class="arithmatex">\(\text{ZFC}\)</span>. When it was proven to be independent, it split the world of set theory in two, just like PP did. But this time it's worse, because there is a large amount of disagreement among set theorists about whether CH is intuitively true. If you tried to get <span class="arithmatex">\(\text{ZFC} \cup \{\text{CH}\}\)</span> accepted as the foundation of mathematics (instead of <span class="arithmatex">\(\text{ZFC} \cup \{\lnot \text{CH}\}\)</span> or just <span class="arithmatex">\(\text{ZFC}\)</span>), you would get significant pushback from set theorists, beacuse to them, both worlds are equally interesting.</p>
<p>You might hold out hope that alright, fine, <span class="arithmatex">\(\text{ZFC}\)</span> has some independent sentences, but they're sentences we didn't really care about anyway. This is actually mostly true if you're not a set theorist and don't work with graduate level math! Most sentences independent of <span class="arithmatex">\(\text{ZFC}\)</span> come from set theory, and the rest are complicated statements in other fields, most of which I don't even understand the statement of.<sup id="fnref:4"><a class="footnote-ref" href="proxy.php?url=#fn:4">4</a></sup> But the incompleteness theorem puts a "cap", so to speak, on <span class="arithmatex">\(\text{ZFC}\)</span> (and thus mathematics): the deeper into a subject you go, the closer and closer you brush up against independent statements. And if you're particularly unlucky, you'll actually run into a theorem in your work which is independent of <span class="arithmatex">\(\text{ZFC}\)</span>, and you'll curse the incompleteness theorem when you do.</p>
<p>So, sentences being independent of a theory is bad, and all theories which can serve as the fondation of mathematics have independent sentences (because they are, to a tee, sufficiently strong). This is the single most important implication of the incompleteness theorem.</p>
<h2>Incompleteness of <span class="arithmatex">\(T_{group}\)</span></h2>
<p>But wait — if a theory <span class="arithmatex">\(T\)</span> being incomplete is bad, and we proved that <span class="arithmatex">\(T_{group}\)</span> is incomplete above, isn't that bad news for group theorists? Well, it's not <em>good</em>, but it's also not bad. It's true that <span class="arithmatex">\(\sigma_{abelian}\)</span> splits <span class="arithmatex">\(T_{group}\)</span> into two theories: <span class="arithmatex">\(T_{group} \cup \{\sigma_{abelian}\}\)</span> and <span class="arithmatex">\(T_{group} \cup \{\lnot \sigma_{abelian}\}\)</span>. But these are just the theories of abelian and non-abelian groups respectively. If I had asked you whether studying abelian and non-abelian groups separately bothers you, you would have looked at me like I'm crazy. After all, if you want to prove something about abelian groups, you just assume that <span class="arithmatex">\(G\)</span> is abelian (but note that this is identical to working in <span class="arithmatex">\(T_{group} \cup \{\sigma_{abelian}\}\)</span>).</p>
<p>The difference lies in that <span class="arithmatex">\(T_{group}\)</span> is not trying to be a theory of mathematics. You don't particularly care if you can't prove every possible statement for all groups, because if you can't, you can always look at a specific group you care about and prove whether that statement is true in that group or not. This isn't possible in a theory of mathematics.<sup id="fnref:5"><a class="footnote-ref" href="proxy.php?url=#fn:5">5</a></sup></p>
<h2>Completeness of <span class="arithmatex">\(T_{EG}\)</span></h2>
<p>But wait — we said earlier that the theory of euclidean geometry, <span class="arithmatex">\(T_{EG}\)</span>, was complete. Does this contradict the incompleteness theorem? No, because <span class="arithmatex">\(T_{EG}\)</span> is not "sufficiently strong". There are a number of interesting theories which are complete, like <span class="arithmatex">\(T_{EG}\)</span>, but aren't strong enough to be subject to the incompleteness theorem.</p>
<h2>"Completing" a theory</h2>
<p>Recall that we saw <span class="arithmatex">\(T_{NG}\)</span> (neutral geometry), which is incomplete, could be extended to a complete theory <span class="arithmatex">\(T_{EG}\)</span> (euclidean geometry) by adding the parallel postulate. We say that <span class="arithmatex">\(T_{EG}\)</span> is a "completion" of <span class="arithmatex">\(T_{NG}\)</span>, that <span class="arithmatex">\(T_{NG}\)</span> can be "completed" by adding PP, etc.</p>
<p>You might wonder if we could pull the same trick for theories affected by the incompleteness theorem. Given some sufficiently strong theory <span class="arithmatex">\(T\)</span>, the incompleteness theorem says there is some <span class="arithmatex">\(\sigma\)</span> independent of <span class="arithmatex">\(T\)</span>. Could we complete <span class="arithmatex">\(T\)</span> by adding either <span class="arithmatex">\(\sigma\)</span> or <span class="arithmatex">\(\lnot \sigma\)</span> to <span class="arithmatex">\(T\)</span> as an axiom? The answer is no, regardless of which we choose. Adding an axiom to a theory never makes that theory weaker (ie prove less sentences) — it can only make it stronger. This new theory <span class="arithmatex">\(T' = T \cup \{\sigma\}\)</span> would still be sufficiently strong and thus satisfy the incompleteness theorem, so there is some new sentence <span class="arithmatex">\(\sigma'\)</span> which is independent of <span class="arithmatex">\(T'\)</span>.</p>
<p>So no matter how many independent sentences we add as axioms to a sufficiently strong theory, it will still be sufficiently strong and subject to the incompleteness theorem. A sufficiently strong theory can never be "completed".</p>
<h1>Independent sentences are "true"</h1>
<p>This misunderstanding (I'm tempted to say "abuse") is the singular reason I wrote this post, so you'll have to forgive me if I rant a bit here. The single most common misuse of the incompleteness theorem is stating that the independent sentence is somehow "true". Here's a direct quote <a href="proxy.php?url=https://en.wikipedia.org/wiki/G%C3%B6del%27s_incompleteness_theorems">from wikipedia</a>:</p>
<div class="quote">For any such consistent formal system, there will always be statements about natural numbers that are true, but that are unprovable within the system.</div>
<p>(They're using "consistent formal system" to be some theory <span class="arithmatex">\(T\)</span>, "statements about the natural numbers" to be some sentence <span class="arithmatex">\(\sigma\)</span>, and "unprovable within the system" to mean "independent of <span class="arithmatex">\(T\)</span>").</p>
<p>Except this is wrong. An independent sentence <span class="arithmatex">\(\sigma\)</span> is absolutely not "true". It is, <em>by definition</em>, true in some model <span class="arithmatex">\(\mathcal{A} \vDash T\)</span> and false in some other model <span class="arithmatex">\(\mathcal{B} \vDash T\)</span>, so calling it "true" is nonsense. It's neither true nor false; it's independent.</p>
<p>What people really mean when they say that an independent sentence <span class="arithmatex">\(\sigma\)</span> is true is that it's true in the "standard model", and therefore, they argue, intuitively true. What is the standard model? Nothing more than a particular model <span class="arithmatex">\(\mathcal{A} \vDash T\)</span> we have arbitrarily chosen as intuitive for visualizing <span class="arithmatex">\(T\)</span>. For instance, the standard model of euclidean geometry <span class="arithmatex">\(T_{EG}\)</span> is the plane <span class="arithmatex">\(\mathbb{R}^2\)</span>.</p>
<p>But for other theories, it's not clear at all what the standard model is – say, for <span class="arithmatex">\(T_{group}\)</span>. You might suggest $<span class="arithmatex">\((\mathbb{Z}, +)\)</span>$, but there's no good reason to choose that group over, say $<span class="arithmatex">\((\mathbb{Z}_8, +)\)</span>$, or even $<span class="arithmatex">\(GL(2, \mathbb{R})\)</span>$. Here, the concept of a "standard model" breaks down.</p>
<p>For theories which have a standard model, this line of thinking does have some philosophical merit. I just wish people would say "there is a sentence which cannot be proven from <span class="arithmatex">\(T\)</span> but is true in the standard model", instead of saying "there is a true sentence which cannot be proven", which sounds like a contradiction. This seeming contradiction bothered me for many years when reading about the incompleteness theorem, and I was greatly relieved to eventually learn that people were simply misinterpreting the theorem.</p>
<h2>Gödel's completeness theorem</h2>
<p>Before his incompleteness theorem, Gödel proved another theorem about the completeness of first order logic. Informally, this theorem says that for all theories <span class="arithmatex">\(T\)</span> and sentences <span class="arithmatex">\(\sigma\)</span>, if <span class="arithmatex">\(\sigma\)</span> is true in every model <span class="arithmatex">\(\mathcal{A} \vDash T\)</span>, then there is a proof of <span class="arithmatex">\(\sigma\)</span> from the axioms of <span class="arithmatex">\(T\)</span>. In other words, there is a proof of every true statement.</p>
<p>The naming of these theorems suggests a contradiction: how can we have both Gödel's completeness theorem and Gödel's incompleteness theorem?</p>
<p>Well, because they refer to two different notions of completeness. "completeness" in the completeness theorem means that "everything which is true is provable". However, "incompleteness" in the incompleteness theorem means that some theories <span class="arithmatex">\(T\)</span> have sentences which are neither true nor false in <span class="arithmatex">\(T\)</span>. These independent sentences don't even satisfy the conditions of the completeness theorem (since they're not true in every model), so these two theorems are entirely orthogonal.</p>
<h1>Technicalities</h1>
<p>I haven't been entirely truthful with you. There are two extra assumptions we need to add before we get the true incompleteness theorem. They deal with what are essentially edge cases – though very important edge cases.</p>
<h2>Satisfiable</h2>
<p>First, we require that the theory <span class="arithmatex">\(T\)</span> be <strong>satisfiable</strong>. A theory <span class="arithmatex">\(T\)</span> is <strong>satisfiable</strong> if there is any model <span class="arithmatex">\(\mathcal{A} \vDash T\)</span> at all. Equivalently, <span class="arithmatex">\(T\)</span> is satisfiable if its axioms are consistent, ie you can't derive a contradiction from them. If we allowed <span class="arithmatex">\(T\)</span> to be unsatisfiable, then the incompleteness theorem would fail in the trivial case: let <span class="arithmatex">\(T\)</span> be any sufficiently strong, unsatisfiable theory. Then there are no models <span class="arithmatex">\(\mathcal{A} \vDash T\)</span>, so vacuously, there are no independent sentences <span class="arithmatex">\(\sigma\)</span> (since an independent sentence requires at least two models). But this would contradict the incompleteness theorem.</p>
<p>Here's our updated incompleteness theorem:</p>
<div class="quote">For any sufficiently strong, satisfiable theory $T$, there is a sentence $\sigma$ which is independent of $T$.</div>
<h2>Recursively enumerable</h2>
<p>For what are actually pretty technical reasons, we also require <span class="arithmatex">\(T\)</span> to "recursively enumerable". This is equivalent to saying that the elements of <span class="arithmatex">\(T\)</span> are "computable", ie there is an algorithm which, given any sentence <span class="arithmatex">\(\sigma\)</span>, returns true if <span class="arithmatex">\(\sigma \in T\)</span> and false otherwise. It's not worth getting into the details here, but this basically rules out crazy theories where you just throw in so many axioms that you're eventually able to prove everything in all models. Any "reasonable" theory like <span class="arithmatex">\(\text{ZFC}\)</span> or <span class="arithmatex">\(Q\)</span> is recursively enumerable.</p>
<p>You might also see such theories being called "decidable", as in, you can "decide" whether a sentence <span class="arithmatex">\(\sigma\)</span> is an element of <span class="arithmatex">\(T\)</span>.<sup id="fnref:6"><a class="footnote-ref" href="proxy.php?url=#fn:6">6</a></sup></p>
<p>So our updated incompleteness theorem is then:</p>
<div class="quote">For any sufficiently strong, satisfiable, recursively enumerable theory $T$, there is a sentence $\sigma$ which is independent of $T$.</div>
<p>You can see why I didn't want to lead with this definition :)</p>
<p>I promise that I'm not holding anything back anymore — this is the genuine, full incompleteness theorem which Gödel himself proved<sup id="fnref:7"><a class="footnote-ref" href="proxy.php?url=#fn:7">7</a></sup>. These extra assumptions rarely come up in casual discussions, which is why I left them until now to discuss.</p>
<h1>Afterword</h1>
<p>I debated a lot about which examples of theories to use, and in fact originally wrote a draft where I used the theory of real-valued vector spaces. Unfortunately, its axiomatization is quite dirty, and so I dropped it in favor of the theory of groups, even though I think more people would be familiar with vector spaces than groups. Oh well.</p>
<p>There are also some philosophical implications I wanted to include, but I don't feel qualified to discuss them. I'm also not really convinced how big the philosophical implications of the incompleteness theorem are.</p>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>Since theories consist of sentences, and sentences depend on a language, you would be right to suspect that theories also depend on a language. Formally we call a theory <span class="arithmatex">\(T\)</span> an <span class="arithmatex">\(L\)</span>-theory, where L is the language of the theory. We again drop the <span class="arithmatex">\(L\)</span>- prefix when the langauge is clear from context. <a class="footnote-backref" href="proxy.php?url=#fnref:1" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li id="fn:2">
<p>If <span class="arithmatex">\(\sigma\)</span> is true in <span class="arithmatex">\(\mathcal{A}\)</span>, you'll see this written in the literature as <span class="arithmatex">\(\mathcal{A} \vDash \sigma\)</span>. However, you'll see very shortly that this is an overloading of the <span class="arithmatex">\(\vDash\)</span> operator; its meaning changes depending on if the right hand side is a sentence <span class="arithmatex">\(\sigma\)</span> or a theory <span class="arithmatex">\(T\)</span>. I've avoided writing <span class="arithmatex">\(\mathcal{A} \vDash \sigma\)</span> here for clarity, but it is the more precise usage. <a class="footnote-backref" href="proxy.php?url=#fnref:2" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
<li id="fn:3">
<p>Proving that euclidean geometry is complete requires a more formal axiomatization than what Euclid gave, and so we turn to <a href="proxy.php?url=https://en.wikipedia.org/wiki/Tarski%27s_axioms">Tarski's Axioms</a> (sometimes called elementary euclidean geometry) instead. This is outside the scope of this post, but Tarski proved that his theory was complete by showing that it admits quantifier elimination. Completeness follows from this since the language has no constants, which means the only sentences without quantifiers are <span class="arithmatex">\(\top\)</span> and <span class="arithmatex">\(\bot\)</span>, which are true and false in every model respectively. <a class="footnote-backref" href="proxy.php?url=#fnref:3" title="Jump back to footnote 3 in the text">↩</a></p>
</li>
<li id="fn:4">
<p>See <a href="proxy.php?url=https://en.wikipedia.org/wiki/List_of_statements_independent_of_ZFC">List of statements independent of ZFC</a>. <a class="footnote-backref" href="proxy.php?url=#fnref:4" title="Jump back to footnote 4 in the text">↩</a></p>
</li>
<li id="fn:5">
<p>This is because any theory of mathematics can't prove that there are any models of that theory, or else the theory would be consistent, which contradicts Gödel's second incompleteness theorem. So there are no "specific models" of a theory of mathematics to look at — in fact, there are no models of a theory of mathematics at all. <a class="footnote-backref" href="proxy.php?url=#fnref:5" title="Jump back to footnote 5 in the text">↩</a></p>
</li>
<li id="fn:6">
<p>The multitude of names is thanks to computability theory, which proved that several distinct notions of computability (all with their own names) are actually exactly equivalent, and thus the names are interchangeable. <a class="footnote-backref" href="proxy.php?url=#fnref:6" title="Jump back to footnote 6 in the text">↩</a></p>
</li>
<li id="fn:7">
<p>Ok, fine, you got me: Gödel's original proof required something called <a href="proxy.php?url=https://en.wikipedia.org/wiki/%CE%A9-consistent_theory"><span class="arithmatex">\(\omega\)</span>-consistency</a>, a strengthening of consistency. However, it turns out this condition can be weakened to consistency alone, with <a href="proxy.php?url=https://en.wikipedia.org/wiki/Rosser%27s_trick">Rosser's trick</a>. <a class="footnote-backref" href="proxy.php?url=#fnref:7" title="Jump back to footnote 7 in the text">↩</a></p>
</li>
</ol>
</div>