<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title></title>
		<description>Machine Logic is Lawrence Paulson&apos;s blog on Isabelle/HOL and related topics.</description>
		<link>https://lawrencecpaulson.github.io/</link>
		<atom:link href="https://lawrencecpaulson.github.io//feed.xml" rel="self" type="application/rss+xml" />
		
			<item>
				<title>Memories: doing my PhD at Stanford, under John L Hennessy</title>
				<description>&lt;p&gt;When young researchers get together, one topic of conversation is “who supervised your PhD?”
Back in the day, Rod Burstall was often named. 
Also mentioned were Robin Milner, Dana Scott and Gordon Plotkin.
Then it would be my turn: “&lt;a href=&quot;https://profiles.stanford.edu/john-hennessy&quot;&gt;John Hennessy&lt;/a&gt;”. Who?
Even today, while everyone has heard of Mark Zuckerberg and Bill Gates, few people can name
the guy who is in charge of Google’s sprawling empire.
But even those who got past the “who?” would then be asking “why?”&lt;/p&gt;

&lt;h3 id=&quot;early-years-at-stanford&quot;&gt;Early years at Stanford&lt;/h3&gt;

&lt;p&gt;I arrived in the autumn of 1977. It was not a good time for me.
After a year of drifting, I found myself in the group of David Luckham 
and his &lt;a href=&quot;http://i.stanford.edu/pub/cstr/reports/cs/tr/79/731/CS-TR-79-731.pdf&quot;&gt;Stanford Pascal Verifier&lt;/a&gt;.
It consisted of a &lt;a href=&quot;https://en.wikipedia.org/wiki/Verification_condition_generator&quot;&gt;verification condition generator&lt;/a&gt; 
for Pascal coupled with a rewriting engine
for proving the assertions generated. The user had to supply the rewrite rules, 
which had to be trusted: a major weakness.
I worked on verifying list processing programs for a while 
(simple things like &lt;em&gt;append&lt;/em&gt; and &lt;em&gt;reverse&lt;/em&gt;), but came a cropper when I noticed that
the rewrite rules for lists that I had been given were inconsistent.&lt;/p&gt;

&lt;p&gt;Luckham had a strong group. In particular, &lt;a href=&quot;https://en.wikipedia.org/wiki/Greg_Nelson_(computer_scientist)&quot;&gt;Greg Nelson&lt;/a&gt; 
and &lt;a href=&quot;&quot;&gt;Derek Oppen&lt;/a&gt; made contributions 
that are still used today in most SMT solvers:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://dl.acm.org/doi/10.1145/322186.322198&quot;&gt;congruence closure&lt;/a&gt;, 
whereby all available equalities are propagated throughout a formula&lt;/li&gt;
  &lt;li&gt;a cooperation framework for &lt;a href=&quot;https://doi.org/10.1145/357073.357079&quot;&gt;combining decision procedures&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In addition, Derek Oppen created a framework for 
&lt;a href=&quot;https://dl.acm.org/doi/10.1145/357114.357115&quot;&gt;pretty printing&lt;/a&gt; 
that I adopted every chance I got, which means it is now in HOL4, Isabelle
and the &lt;a href=&quot;https://polyml.org&quot;&gt;Poly/ML&lt;/a&gt; implementation of &lt;a href=&quot;https://doi.org/10.1145/3386336&quot;&gt;Standard ML&lt;/a&gt;.
Unfortunately, David Luckham had a reputation for exploiting his PhD students; 
I was even taken aside, probably by the kind and lovely departmental secretary, Carolyn Tajnai, and advised to watch out.
Unfortunately, I was by nature inattentive, so I didn’t take heed 
and I didn’t even notice when (allegedly) Luckham told me that I should move on.
But I did notice when my financial support disappeared.&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; Enter John.&lt;/p&gt;

&lt;h3 id=&quot;working-with-john-hennessy&quot;&gt;Working with John Hennessy&lt;/h3&gt;

&lt;p&gt;My first impression was that John looked incredibly young.
Compared with Luckham and many other Stanford professors, he was practically a baby (he was 27).
It must’ve been a challenge for him as well as myself.
I was there because I had gotten into trouble and needed funding, 
which is not the most promising start for the professor/student relationship.
I was interested in programming languages and theory, 
while his speciality was computer architecture.
Somehow we arrived at a PhD project involving 
theory (&lt;a href=&quot;https://podcasts.ox.ac.uk/keywords/denotational-semantics&quot;&gt;denotational semantics&lt;/a&gt;) 
and practice (in the form of compiler generation).
Somehow I started building the thing. At first it wasn’t working, then it was.
I had built a &lt;a href=&quot;https://doi.org/10.1145/582153.582178&quot;&gt;semantics-directed compiler generator&lt;/a&gt; consisting of three components:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;a &lt;em&gt;Grammar Analyser&lt;/em&gt;, which took a programming language specification 
in the form of an &lt;a href=&quot;https://rdcu.be/e3PLO&quot;&gt;attribute grammar&lt;/a&gt; 
decorated with formulas of denotational semantics&lt;/li&gt;
  &lt;li&gt;a &lt;em&gt;Universal Translator&lt;/em&gt;, which functioned as a compiler for the specified language&lt;/li&gt;
  &lt;li&gt;a &lt;em&gt;Stack Sachine&lt;/em&gt;, for executing the generated code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The performance penalty for the generated object code was a factor of 1000, but who’s counting?&lt;/p&gt;

&lt;p&gt;To support myself, generally I worked as a Teaching Assistant and 
gave the occasional lecture standing in for John, 
but on the whole I was simply able to get on with my research.
And at the end when I had finished too quickly to satisfy Stanford’s residence requirement,
John even found the money to pay the difference.
(You can’t do that at Cambridge, but the residence requirement is only three years.)&lt;/p&gt;

&lt;p&gt;At Stanford, like in many other universities, the PhD defence is a public event.
Moreover, the candidate is supposed to bring refreshments, generally something like donuts. 
I decided to bring milk and cookies. This was a stupid idea. 
I wasn’t good at baking cookies (a housemate helped me out when it all went wrong), 
and it isn’t wise to pretend that your PhD defence is some sort of kindergarten.&lt;/p&gt;

&lt;h3 id=&quot;watching-him-rise-and-rise&quot;&gt;Watching him rise and rise&lt;/h3&gt;

&lt;p&gt;After getting my PhD, and with John’s advice and help, I found myself at Cambridge.
While mostly preoccupied with my research, I got occasional news from Stanford.
John’s career trajectory went like this:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;1989: Director of the Computer System Laboratory [a research unit within the CS department]&lt;/li&gt;
  &lt;li&gt;1994: Chairman of the Computer Science Department&lt;/li&gt;
  &lt;li&gt;1996: Dean of the School of Engineering&lt;/li&gt;
  &lt;li&gt;1999: Provost of Stanford University&lt;/li&gt;
  &lt;li&gt;2000: President of Stanford University&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;He remained President of Stanford until 2016. Where does one go up from there?
President of the USA would be a weak and frustrating role, at least back in that quaint time 
when the President’s powers were limited by the US Constitution.
If you really want to be master of the universe, take charge of Google.
He did that in 2018.&lt;/p&gt;

&lt;p&gt;Up until now I have not mentioned John’s research. 
(I was not one to follow developments in computer architecture.)
John, with David Patterson, made fundamental contributions 
to the development of RISC technology and wrote two acclaimed textbooks.
John was also a founder of &lt;a href=&quot;https://en.wikipedia.org/wiki/MIPS_architecture_processors&quot;&gt;MIPS Computer Systems&lt;/a&gt;.
His work has been recognised by the ACM’s Turing Award and numerous other honours and prizes.
If your computer is fast, one of the people you should thank is John.&lt;sup id=&quot;fnref:2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;h3 id=&quot;as-an-influence&quot;&gt;As an influence&lt;/h3&gt;

&lt;p&gt;If asked whom I see as role models, I typically mention &lt;a href=&quot;https://feynman.com&quot;&gt;Richard Feynman&lt;/a&gt; and John Hennessy. 
It may be ridiculous to name Nobel and Turing laureates, 
but why not aim high? Seriously, what I tried to emulate is not genius or ambition, 
but their willingness to engage with students. Feynman, despite his celebrity, 
went out of his way to communicate his knowledge to lowly undergraduates, 
never hiding behind mathematical formulas 
but revealing their link to natural phenomena.
John did not understand exactly what I was doing.
But he had already grasped that this was not necessary.
It is enough to guide the student through the labyrinth of the PhD process, 
keeping an eye on their progress and recognising when they needed help.
Think of a General Practitioner who has overall familiarity with their patient’s health situation and knows when to refer them to a specialist.&lt;/p&gt;

&lt;p&gt;John visited Cambridge during the 1990s, perhaps interested in 
taking up a position here. So in a plausible alternative future, 
he might now be the British Prime Minister.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;I was not unhappy to learn, years later, about an unfortunate situation involving airport security that got Luckham an invitation to spend a night in a police cell. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;And if it is slow, probably you should be blaming Bill Gates. &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
				<pubDate>Fri, 13 Feb 2026 00:00:00 +0000</pubDate>
				<link>https://lawrencecpaulson.github.io//2026/02/13/John_Hennessy.html</link>
				<guid isPermaLink="true">https://lawrencecpaulson.github.io//2026/02/13/John_Hennessy.html</guid>
			</item>
		
			<item>
				<title>Broken proofs and broken provers</title>
				<description>&lt;p&gt;People expect perfection. Consider the reaction when someone who has been vaccinated 
against a particular disease nevertheless dies of it.
Mathematical proof carries the aura of perfection, but again people’s expectations will sometimes be dashed.
As outlined in an &lt;a href=&quot;/2025/09/05/All_or_nothing.html&quot;&gt;earlier post&lt;/a&gt;,
the verification of a real world system is never finished.
We can seldom capture 100% of reality, so failure remains possible.
Even in a purely mathematical proof, there are plenty of ways to screw up.
Plus, proof assistants have bugs.&lt;/p&gt;

&lt;h3 id=&quot;some-badly-broken-proofs&quot;&gt;Some badly broken proofs&lt;/h3&gt;

&lt;p&gt;Many years ago, I refereed a paper about the verification of some obscure application. I recall that 
the theoretical framework depended on several parameters,
among them $z$, a nonzero complex number.
This context was repeated for all the theorems in the paper:
each included the assumption $\forall z.\, z\not=0$.
Needless to say, that assumption is flatly false.
The author of the paper had presumably intended to write something like
$\forall z.\, z\not=0 \to \cdots$.
The error is easy to overlook, 
and I only became suspicious because the proofs looked too simple. The entire development was invalid.&lt;/p&gt;

&lt;p&gt;Isabelle would have helped here.
For one thing, Sledgehammer warns you if it detects a contradiction 
in your background theory.
And also, when you have a series of theorems that all depend on the same context,
you can prove them within a &lt;a href=&quot;/2022/03/23/Locales.html&quot;&gt;locale&lt;/a&gt;, with assumptions such as $z\not=0$ laid out clearly.
Even without locales, the Isabelle practice of listing the assumptions 
separately in the theorem statement would have avoided the problem.
Isabelle newbies frequently ask why we prefer inference rules with explicit premises and conclusions over formulas like $\forall x.\,P(x) \to Q(x)$.
It is to avoid the confusing clutter of quantifiers and implications and 
the further clutter of the proof steps needed to get rid of them
(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;intros&lt;/code&gt; in Rocq).&lt;/p&gt;

&lt;p&gt;But in some cases, Isabelle itself can be the problem.
Once, a student had proved some false statement
and then used it to prove all the other claims (easily!).
But how did he prove the false statement in the first place?
Actually he didn’t: his proof was stuck in a loop.
By a quirk of multithreading: when processing a theory file,
If one Isabelle thread gets bogged down, 
other threads will still race ahead under the assumption 
that the bogged-down proof will eventually succeed.
Such issues are easily identified if you run your theory in batch mode: 
it would simply time out.
I have given an example of this error in &lt;a href=&quot;/2022/05/11/jEdit-tricks.html&quot;&gt;another post&lt;/a&gt;.
Experienced users know to be wary when proofs go through too easily.&lt;/p&gt;

&lt;p&gt;Another way to prove nonsense is getting your definitions wrong.
With luck, the lemmas that you have to prove about your definitions
will reveal any errors. Apart from that, you will be okay provided the 
definitions do not appear in the main theorem.
Recently I completed a &lt;a href=&quot;https://doi.org/10.4230/LIPIcs.ITP.2025.18&quot;&gt;large proof&lt;/a&gt; 
where I was deeply unsure that I understood the subject matter.
Fortunately, the headline result included none 
of the intricate definitions involved in the work.
The key point is that making a definition in a proof assistant does not compromise its consistency.
If the definition is wrong, theorems mentioning it will not mean what you think they mean, but you will not be able to prove $1=0$.&lt;/p&gt;

&lt;p&gt;This is also the answer to those who complain that $x/0=0$ in Isabelle 
(also, in HOL and Lean): 
if your theorem does not mention&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; the division symbol then it doesn’t matter.
And if it does mention division, then the only possible discrepancy 
between Isabelle’s interpretation and the traditional one 
involves division by zero; in that case, 
there is no traditional interpretation to disagree with.&lt;/p&gt;

&lt;h3 id=&quot;soundness-bugs-in-proof-assistants&quot;&gt;Soundness bugs in proof assistants&lt;/h3&gt;

&lt;p&gt;We expect proof assistants to be correct, but how trustworthy are they really?
I spent a little time tracking down soundness errors in a few of them:
first, naturally, Isabelle, where there has been one error every 10 years.&lt;/p&gt;

&lt;p&gt;In 2025 (last February), somebody showed &lt;a href=&quot;https://lists.cam.ac.uk/sympa/arc/cl-isabelle-users/2025-02/msg00111.html&quot;&gt;how to prove &lt;strong&gt;false&lt;/strong&gt;&lt;/a&gt;
in Isabelle/HOL using normalisation by evaluation, 
which bypasses the proof kernel.
This was not a kernel bug, and unlikely to bump into by accident, 
but it was obviously unacceptable and was fixed in the following Isabelle release.&lt;/p&gt;

&lt;p&gt;In 2015, Ondřej Kunčar found a bug in Isabelle/HOL’s treatment of overloaded definitions.
A particularly cunning circular definition was accepted
and could be used to &lt;a href=&quot;/2025/06/04/Definitions.html&quot;&gt;prove &lt;strong&gt;false&lt;/strong&gt;&lt;/a&gt;.
I recall arguing that this was not really a soundness bug.
But just above, I have noted how important it is 
that definitions preserve consistency:
in particular, that they can be eliminated (in principle) by substitution.
&lt;a href=&quot;https://eprints.whiterose.ac.uk/id/eprint/191505/1/Consistent_Foundation_IsabelleHOL_JAR_2019.pdf&quot;&gt;Kunčar and Popescu&lt;/a&gt; put a great effort into not just fixing this bug but putting the definition mechanism onto a sound theoretical bases.&lt;/p&gt;

&lt;p&gt;In 2005, Obua discovered that essentially no checks were being performed on overloaded definitions. He discovered a not-quite-so cunning circular definition that could be used to prove &lt;strong&gt;false&lt;/strong&gt;
(details in the &lt;a href=&quot;https://eprints.whiterose.ac.uk/id/eprint/191505/1/Consistent_Foundation_IsabelleHOL_JAR_2019.pdf&quot;&gt;previous paper&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;There must have been earlier soundness bugs in Isabelle, 
but I cannot remember any beyond those above.
Definitions were not being checked for circularity
because Isabelle was specialised research software and I couldn’t be bothered to stop people from hanging themselves: that old UNIX spirit.
But good computer systems do protect users.&lt;/p&gt;

&lt;p&gt;An early soundness bug in HOL88 also involved definitions.
It was omitting to check that all the variables on the right hand side 
of the definition also appeared on the left-hand side.
That leads to a contradiction trivially.
A subtler error is to allow a definition where 
the right hand side is “more polymorphic” than the left
and depends on some property of a type.&lt;/p&gt;

&lt;p&gt;I can still remember a soundness bug that I introduced into LCF 40 years ago.
I was coding &lt;em&gt;𝛼-conversion&lt;/em&gt;: a function to test 
whether two λ-expressions were equivalent up to renaming of bound variables. 
For example, $\lambda x.x$ and $\lambda y.y$ are 𝛼-equivalent.
But I was coding in LISP and used a popular optimisation of testing for pointer equality, 
overlooking that it made no sense here.
My code regarded $\lambda x.x$ and $\lambda y.x$ as equivalent.
This sort of bug is particularly dangerous because it is in the kernel.&lt;/p&gt;

&lt;p&gt;I have never heard of any soundness bug in Rocq,
but fortunately, the Rocq team maintain a &lt;a href=&quot;https://github.com/rocq-prover/rocq/blob/master/dev/doc/critical-bugs.md&quot;&gt;convenient list&lt;/a&gt;
of critical bugs. It’s scary, and you have to wonder 
what they did wrong. After all, Lean is based on a similar calculus
and seems to have a good soundness record.
Another seriously buggy proof assistant is PVS;
at least, it was &lt;a href=&quot;https://rdcu.be/eYAoi&quot;&gt;30 years ago&lt;/a&gt;.
PVS has no proof kernel.&lt;/p&gt;

&lt;p&gt;My impression is that the &lt;a href=&quot;https://lawrencecpaulson.github.io/tag/LCF&quot;&gt;LCF style systems&lt;/a&gt;, 
including the HOL family 
as well as Isabelle, have an excellent record for soundness, 
confirming Robin Milner’s conception from half a century ago –
and with no countervailing penalty.&lt;/p&gt;

&lt;h3 id=&quot;so-can-we-rely-on-machine-proofs&quot;&gt;So can we rely on machine proofs?&lt;/h3&gt;

&lt;p&gt;Of the woeful tales related above, 
I am not aware of any that had practical implications.
Even soundness bugs seem to have a limited impact.
Griffioen and Huisman &lt;a href=&quot;https://rdcu.be/eYAoi&quot;&gt;wrote&lt;/a&gt; of PVS&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The obvious question thus arises, why use a proof tool that probably contains soundness bugs? … PVS is still a very critical reader of proofs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A close examination of almost any proof published in a mathematics journal
will identify errors.
Most are easy to fix, but the persistence of errors must undermine our confidence in published mathematics.
Let’s recall once again that remarkable group of footnotes from 
&lt;em&gt;The Axiom of Choice&lt;/em&gt;, by T J Jech:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/Jech-118-footnotes.png&quot; alt=&quot;Footnotes from Jech&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This exact list &lt;a href=&quot;/2025/03/14/revisiting_demillo.html&quot;&gt;was used by DeMillo et al.&lt;/a&gt;
as evidence for the strength of the mathematical community 
and decades later, in my own grant proposal, as evidence for its weakness.
In the case of machine proofs, 
with the crucial caveat that abstract models of the real world
often turn out to be inadequate, 
we do not find errors. Evidence from testing suggests that verification works.&lt;/p&gt;

&lt;p&gt;In my corner of the world of interactive theorem proving, 
we take soundness seriously.
Mike Gordon strongly promoted a &lt;em&gt;definitional approach&lt;/em&gt;: no axioms ever, 
all proof developments built upon pure higher-logic from definitions alone, to avoid any danger of inconsistency.
Many of the variants of the HOL system owe their existence 
to a desire for ever greater rigour.
For example, &lt;a href=&quot;https://doi.org/10.1007/978-3-642-03359-9_4&quot;&gt;John Harrison writes&lt;/a&gt; 
“HOL Light is distinguished by its clean and simple design 
and extremely small logical kernel.”
The HOL light kernel was &lt;a href=&quot;https://doi.org/10.1007/s10817-015-9357-x&quot;&gt;later verified&lt;/a&gt;.
The apotheosis of this project is the
&lt;a href=&quot;https://cakeml.org/candle/&quot;&gt;Candle theorem prover&lt;/a&gt;, created by porting HOL Light to the CakeML language. 
Candle has been proved to correctly implement higher-order logic, 
and moreover, this theorem has been established for its compiled machine code.
We have no way of knowing whether higher-order logic is consistent, 
but if it isn’t, there will be nothing left of mathematics.&lt;/p&gt;

&lt;p&gt;Incidentally, higher-order logic is remarkably self-contained.
Over past decades, the HOL provers and Isabelle/HOL have gained numerous extensions: recursive datatypes, 
general recursive function definitions with pattern matching, 
inductive definitions and coinductive definitions. 
These are all definable within higher order logic, whereas similar capabilities in dependent type theories always seem 
to require extensions to the kernel. 
And that means, any bugs are kernel bugs.
In view of the much greater logical strength of dependent type theories, this situation is hard to understand.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;directly or indirectly (see the first comment below) &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
				<pubDate>Thu, 15 Jan 2026 00:00:00 +0000</pubDate>
				<link>https://lawrencecpaulson.github.io//2026/01/15/Broken_proofs.html</link>
				<guid isPermaLink="true">https://lawrencecpaulson.github.io//2026/01/15/Broken_proofs.html</guid>
			</item>
		
			<item>
				<title>50 years of proof assistants</title>
				<description>&lt;p&gt;Crackpots ranging from billionaire Peter Thiel to random YouTube influencers claim that science has been stagnating for the past 50 years. They admit that computing is an exception: they don’t pretend that my personal 32GB laptop is not an advance over the 16MB mainframe that served the whole Caltech community when I was there. Instead they claim that advances in computing were driven solely by industrial research, quite overlooking the role of academia 
and government funding
in pushing the VLSI revolution, RISC processor design, networking, hypertext, virtual memory and indeed computers themselves. As for the industrial research,
most of it came from just two “blue sky” institutes – &lt;a href=&quot;https://sites.stat.columbia.edu/gelman/research/published/bell.pdf&quot;&gt;Bell Labs&lt;/a&gt; 
and &lt;a href=&quot;https://spectrum.ieee.org/xerox-parc&quot;&gt;Xerox PARC&lt;/a&gt; – that closed a long time ago. 
LCF-style proof assistants are a world away from mainstream computing,
so let’s look at 50 years of progress there.&lt;/p&gt;

&lt;h3 id=&quot;19751985-edinburgh-lcf&quot;&gt;1975–1985: Edinburgh LCF&lt;/h3&gt;

&lt;p&gt;The first instance of LCF was Stanford LCF, developed by Robin Milner in 1972, but it was &lt;strong&gt;not&lt;/strong&gt; an LCF-style proof assistant! LCF meant “Logic for Computable Functions”, a quirky formalism based on Scott domains and intended for reasoning about small functional programs. But “LCF-style proof assistant” means one that, like Edinburgh LCF, was coded in some form of 
the ML programming language and provided a proof kernel, 
encapsulated in an abstract type definition, to ensure that a theorem could only be generated 
by applying inference rules to axioms or other theorems:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;… the ML type discipline is used… so that—whatever complex procedures are defined—all values of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;thm&lt;/code&gt; must be theorems, as only inferences can compute such values…. This security releases us from the need to preserve whole proofs… — an important practical gain since large proofs tended to clog up the working space… [&lt;em&gt;Edinburgh LCF&lt;/em&gt;, page IV]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Edinburgh LCF was first announced in 1975, which conveniently is exactly 50 years ago, 
at the almost mythical conference on &lt;em&gt;Proving and Improving Programs&lt;/em&gt; held at Arc-et-Senans. 
The &lt;a href=&quot;https://link.springer.com/book/10.1007/3-540-09724-4&quot;&gt;user manual&lt;/a&gt;, published in the Springer lecture notes series, came out in 1979.
Edinburgh LCF introduced some other principles that people still adhere to today:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;inference rules in the &lt;em&gt;natural deduction&lt;/em&gt; style, with a dynamic set of assumptions&lt;/li&gt;
  &lt;li&gt;a &lt;em&gt;goal-directed&lt;/em&gt; proof style, where you start with the theorem statement and work backwards&lt;/li&gt;
  &lt;li&gt;a structured system of &lt;em&gt;theories&lt;/em&gt; to organise groups of definitions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Edinburgh LCF had its own version of the ML language.
It supported a fragment of first-order logic containing
the logical symbols $\forall$, $\land$ and $\to$ along with
the relation symbols $\equiv$ and $\sqsubseteq$.
It introduced proof tactics and also &lt;em&gt;tacticals&lt;/em&gt;:
operators for combining tactics.
Tactics supported goal-directed proof,
but Edinburgh LCF had no notion of the current goal or anything to help the user manage the tree of subgoals.
Its user interface was simply the ML top level and the various theorem-proving primitives were simply ML functions.
ML stood for &lt;em&gt;metalanguage&lt;/em&gt;, since managing the process of proof was its exact job.&lt;/p&gt;

&lt;p&gt;Avra Cohn and Robin Milner wrote a &lt;a href=&quot;https://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-20.html&quot;&gt;report&lt;/a&gt; 
on proving the correctness of a parsing algorithm 
using Edinburgh LCF. 
The proof consists of one single induction followed by 
a little simplification and other reasoning.
The report includes a succinct description of Edinburgh LCF.
It is a nice snapshot of the state of the art in 1982,
when I arrived in Cambridge to join a project run by Robin Milner and Mike Gordon.
Full of youthful enthusiasm, I told Mike that it would be great 
if one day we could formalise the Prime Number Theorem.
I hardly knew what the theorem was about or how to prove it, 
but my college roommate had told me it was really deep.&lt;/p&gt;

&lt;p&gt;Disappointed to discover that we only had $\forall$, $\land$ and $\to$,
I set out to fix that, to support full first-order logic. 
I ended up changing so much 
(backwards compatibility is overrated) that people eventually shamed me into writing my own &lt;a href=&quot;https://www.cambridge.org/gb/universitypress/subjects/computer-science/programming-languages-and-applied-logic/logic-and-computation-interactive-proof-cambridge-lcf&quot;&gt;user manual&lt;/a&gt;.
Cambridge LCF never caught on because, well, 
nobody liked the LCF formalism.
But I used it for a development that seemed big at the time: to &lt;a href=&quot;https://doi.org/10.1016/0167-6423(85)90009-7&quot;&gt;verify the unification algorithm&lt;/a&gt;.
This development was later &lt;a href=&quot;https://isabelle.in.tum.de/dist/library/HOL/HOL-ex/Unification.html&quot;&gt;ported to Isabelle&lt;/a&gt;.
It contains 36 inductions, so we were making progress.
And this takes us to 1985, exactly 40 years ago;
see also &lt;a href=&quot;https://doi.org/10.48456/tr-54&quot;&gt;this survey&lt;/a&gt; of the state of play.
But there was almost no mathematics: no negative numbers and no decimal notation, so you could not even write 2+2=4.
As far as the broader computer science community was concerned, we were a joke.&lt;/p&gt;

&lt;h3 id=&quot;19851995-cambridge-lcf-and-hol&quot;&gt;1985–1995: Cambridge LCF and HOL&lt;/h3&gt;

&lt;p&gt;Cambridge LCF was in itself a dead end, but because it included a much faster ML compiler,
it ended up &lt;a href=&quot;/2022/09/28/Cambridge_LCF.html&quot;&gt;being incorporated&lt;/a&gt; into a lot of other proof assistants, notably Mike’s &lt;a href=&quot;https://github.com/theoremprover-museum/HOL88&quot;&gt;HOL88&lt;/a&gt;. 
And just like that, &lt;a href=&quot;/2023/01/04/Hardware_Verification.html&quot;&gt;hardware verification&lt;/a&gt; became a reality. 
Although software verification seemed stuck in the doldrums,
a couple of production-ready chip designs were verified!
Mike’s explanation was that hardware verification was simply easier.&lt;/p&gt;

&lt;p&gt;Also in 1985, we got a new &lt;a href=&quot;https://doi.org/10.1145/3386336&quot;&gt;standard for the ML language&lt;/a&gt;
and, soon, two compilers for it.
So then I started working on experiments that would 
&lt;a href=&quot;/2022/07/13/Isabelle_influences.html&quot;&gt;lead to Isabelle&lt;/a&gt;.
It would be like LCF but would support constructive type theory, 
crucially allowing both unification and backtracking, like in Prolog.
But there was no working system yet, just a grant application. 
And that was the state of play 40 years ago.&lt;/p&gt;

&lt;p&gt;Funding secured, Isabelle development started in earnest in 1986.
It was coded in &lt;a href=&quot;https://www.lfcs.inf.ed.ac.uk/software/ML/&quot;&gt;Standard ML&lt;/a&gt; from the start, while HOL88 was ported from the Cambridge LCF version of ML 
to Standard ML, emerging as HOL90.
Mike acquired a bevy of energetic PhD students, 
who engaged in verification projects or built extensions for HOL.
Versions of HOL were being used in institutes around the world.&lt;/p&gt;

&lt;p&gt;Stepping aside from HOL for a moment, other proof assistants had made great progress 
by the mid 1990s.
The addition of inductive definitions to the calculus of constructions
gave us the &lt;a href=&quot;https://rdcu.be/eR7e8&quot;&gt;calculus of inductive constructions&lt;/a&gt;,
which in essence is the formalism used today by Rocq and Lean.
The very first release of Isabelle/HOL &lt;a href=&quot;https://rdcu.be/eR7gl&quot;&gt;happened in 1991&lt;/a&gt;, 
primarily the work of Tobias Nipkow, though I was soon to
&lt;a href=&quot;https://www.cl.cam.ac.uk/~lp15/Grants/holisa.html&quot;&gt;join in&lt;/a&gt;.
Isabelle/ZF, which was my pet project, formalised axiomatic set theory 
to some &lt;a href=&quot;https://arxiv.org/abs/cs/9612104&quot;&gt;quite deep results&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But I am still not certain whether negative numbers were supported (can somebody help me?).
Our weak support for arithmetic may seem odd 
when our research community was aware that the real numbers 
had been &lt;a href=&quot;/2022/06/22/Why-formalise.html&quot;&gt;formalised in AUTOMATH&lt;/a&gt;, 
but we didn’t seem to want them. 
To many, we were still a joke. This was about to change.&lt;/p&gt;

&lt;h3 id=&quot;19952005-proof-assistants-come-of-age&quot;&gt;1995–2005: Proof assistants come of age&lt;/h3&gt;

&lt;p&gt;In 1994, came the Pentium with its &lt;a href=&quot;https://www.techradar.com/news/computing-components/processors/pentium-fdiv-the-processor-bug-that-shook-the-world-1270773&quot;&gt;FDIV bug&lt;/a&gt;: 
a probably insignificant but detectable error in floating-point division.
The subsequent product recall cost Intel nearly half a billion dollars.
John Harrison, a student of Mike’s, decided to devote his PhD research
to the verification of floating-point arithmetic.
By June 1996 he had submitted an extraordinary &lt;a href=&quot;https://doi.org/10.48456/tr-408&quot;&gt;thesis&lt;/a&gt;, 
&lt;em&gt;Theorem Proving with the Real Numbers&lt;/em&gt;,
which described a formidable series of achievements:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;a formalisation of the real member system in HOL&lt;/li&gt;
  &lt;li&gt;formalised analysis including metric spaces, sequences and series, limits, continuity and differentiation, power series and transcendental functions, integration&lt;/li&gt;
  &lt;li&gt;proper numerals represented internally by symbolic binary, and calculations on them&lt;/li&gt;
  &lt;li&gt;computer algebra techniques including a decision procedure for real algebra&lt;/li&gt;
  &lt;li&gt;tools and techniques for floating-point verification by reference to the IEEE standard&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This thesis, which I had the privilege to examine, won a Distinguished Dissertation Award
and was &lt;a href=&quot;https://link.springer.com/book/10.1007/978-1-4471-1591-5&quot;&gt;published as a book&lt;/a&gt; by Springer.
So by the middle of the 1990s, which was 30 years ago, 
we had gone from almost no arithmetic to a decent chunk of formalised real analysis
that was good enough to verify actual floating-point algorithms.&lt;/p&gt;

&lt;p&gt;This period also saw something of an arms race in automation.
My earlier, Prolog-inspired vision of backtracking search
had led to some &lt;a href=&quot;https://doi.org/10.48456/tr-396&quot;&gt;fairly general automation&lt;/a&gt; that was effective not just in standard predicate logic 
but with any theorems were expressed in a form suitable for forward or backward chaining.
I had also done experiments with classical automatic techniques such as model elimination, which, although pathetic compared with automatic provers of that era, 
was good enough to troll users on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hol-info&lt;/code&gt; mailing list.
Soon I had provoked John Harrison to build a superior version of ME for HOL Light.
Later, Joe Hurd built his &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;metis&lt;/code&gt; superposition prover, which found its way into HOL4.
Not to be outdone, Tobias made Isabelle’s simplifier the best in its class incorporating a number of sophisticated refinements, including some great ideas from Nqthm.&lt;/p&gt;

&lt;p&gt;Twenty years from the start of this chronology we now had 
several reasonably mature and powerful systems, including Isabelle/ZF, Isabelle/HOL, 
multiple versions of the HOL system, and Coq (now Rocq).&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
Many of them used &lt;a href=&quot;https://proofgeneral.github.io&quot;&gt;Proof General&lt;/a&gt;, 
a common user interface for tactic-based proof assistants
based on the Emacs editor.
And we had 100MHz machines, some with 64MB of memory!
We were ready to do big things.&lt;/p&gt;

&lt;p&gt;During this period, I did a lot of work on the 
&lt;a href=&quot;https://doi.org/10.3233/JCS-1998-61-205&quot;&gt;verification of cryptographic protocols&lt;/a&gt;, 
also &lt;a href=&quot;https://doi.org/10.48550/arXiv.2105.06319&quot;&gt;here&lt;/a&gt;.
These secure Internet connections and other network communications;
they are valuable when you need to know who is on the other end 
and need to keep messaging secure from eavesdropping and tampering.
Among the protocols investigated were the ubiquitous TLS
and the late, unlamented SET protocol.
These proofs were not at the level of code or bits;
buggy implementations could and did emerge.&lt;/p&gt;

&lt;p&gt;In 2005, the big thing that caught everyone’s eye
was &lt;a href=&quot;https://rdcu.be/eSgTy&quot;&gt;George Gonthier’s formalisation&lt;/a&gt; (in Coq) 
of the Four Colour Theorem.
Most educated people had heard of the theorem already, 
and its history is fascinating:
numerous proofs had been attempted and rejected since the mid 19th century.
The 1977 proof by Appel and Haken was questioned 
because it relied on a lot of ad-hoc computer code.
Suddenly, despite the still unwelcome involvement of computers, 
no one could doubt the theorem anymore.&lt;/p&gt;

&lt;p&gt;At the opposite extreme was &lt;a href=&quot;https://doi.org/10.1112/S1461157000000449&quot;&gt;my own formalisation&lt;/a&gt; of Gödel’s proof of the relative consistency of the axiom of choice in Isabelle/ZF.
This was the apex of my ZF work, technically difficult but incomprehensible to most people.
My early dream of having a formalisation of the Prime Number Theorem came true in 2005
when Jeremy Avigad &lt;a href=&quot;https://arxiv.org/abs/cs/0509025&quot;&gt;formalised&lt;/a&gt; the theorem in Isabelle.
Somewhat later, John Harrison &lt;a href=&quot;https://rdcu.be/eShga&quot;&gt;formalised a different proof&lt;/a&gt; in HOL Light.
And there was much more. Without any doubt, our systems were capable of serious mathematics.&lt;/p&gt;

&lt;p&gt;Perhaps the most consequential achievement of this period was Mike Gordon’s collaboration 
with Graham Birtwistle and Anthony Fox to &lt;a href=&quot;https://rdcu.be/eShzn&quot;&gt;verify the ARM6 processor&lt;/a&gt;.
Graham, at Leeds, formally specified the instruction set architecture of the processor 
(i.e. the assembly language level), while Mike and Anthony at Cambridge verified the implementation of that architecture in terms of lower level hardware components.
Eventually a &lt;a href=&quot;https://doi.org/10.1145/3290384&quot;&gt;number of other processors&lt;/a&gt; were similarly specified, 
and some verified.
Without any doubt, our systems were capable of serious verification.&lt;/p&gt;

&lt;p&gt;Despite of the focus on applications in this section, 
system development continued in the run-up to 2005.
I am only familiar with Isabelle development, but they were tremendous:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;the &lt;em&gt;Isar language&lt;/em&gt; for structured, legible proofs (a break with the LCF idea that the top level must be a programming language, i.e. ML)&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;axiomatic type classes&lt;/em&gt;, providing principled overloading&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;counterexample finders&lt;/em&gt;: &lt;a href=&quot;https://doi.org/10.1109/SEFM.2004.1347524&quot;&gt;Quickcheck&lt;/a&gt; and Refute (now Nitpick)&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;code generation&lt;/em&gt; from the executable fragment of higher-order logic, and reflection&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;sledgehammer&lt;/em&gt; was under active development, but only ready a couple of years later.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With so much going on, it’s not surprising that our community started doing big things, 
and other people were starting to notice.&lt;/p&gt;

&lt;h3 id=&quot;20052015-the-first-landmarks&quot;&gt;2005–2015: The first landmarks&lt;/h3&gt;

&lt;p&gt;I am not used to phone calls from journalists:
for most of my career, formal verification has been seen as (at best) niche.
But the journalist on the end of the line was asking for information about
&lt;a href=&quot;https://doi.org/10.1145/1629575.1629596&quot;&gt;seL4&lt;/a&gt;, 
the first operating system kernel ever to be formally verified.
Tools for extended static checking were by then able to detect a lot of program faults, but the seL4 verification claimed to cover &lt;em&gt;full functional correctness&lt;/em&gt;: 
the code did exactly what it was supposed to do.
There is now an &lt;a href=&quot;https://sel4.systems&quot;&gt;entire ecosystem&lt;/a&gt; around seL4, 
backed by a million lines of Isabelle/HOL proofs.&lt;/p&gt;

&lt;p&gt;People have wanted to verify compilers 
&lt;a href=&quot;https://doi.org/10.1007/3-540-10886-6&quot;&gt;since forever&lt;/a&gt;.
The task of fully specifying a programming language, target machine 
and compiler already seemed impossible, let alone providing the actual proof.
With &lt;a href=&quot;https://inria.hal.science/hal-01238879v1&quot;&gt;CompCert&lt;/a&gt;, that task was finally fulfilled, for a large subset of the C language:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;What sets CompCert apart from any other production
compiler, is that it is formally verified, using machine-
assisted mathematical proofs, to be exempt from mis-
compilation issues. In other words, the executable code
it produces is proved to behave exactly as specified by
the semantics of the source C program.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A seemingly intractable problem with compiler verification 
was how to translate your verified compiler into machine code.
For example, CompCert is mostly written in Rocq, 
which is then extracted to OCaml code. 
The OCaml compiler had never been verified, 
so how do we know that its compiled code is correct?&lt;sup id=&quot;fnref:2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://cakeml.org&quot;&gt;CakeML&lt;/a&gt; squares this circle through &lt;a href=&quot;https://doi.org/10.1145/3437992.3439915&quot;&gt;bootstrapping&lt;/a&gt;.
CakeML translates from its source language (a dialect of ML) 
to assembly language, accompanied by a proof that the two pieces of code are equivalent.
This work was an outgrowth of the ARM6 project mentioned earlier.
&lt;a href=&quot;https://www.cse.chalmers.se/~myreen/&quot;&gt;Magnus Myreen&lt;/a&gt; 
had &lt;a href=&quot;https://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-765.html&quot;&gt;developed techniques&lt;/a&gt; for
automatically and verifiably translating between assembly language 
and recursive functions in higher-order logic, in both directions.
At the start of the bootstrapping process, 
a tiny compiler was written in pure logic and proved correct.
It was now safe to run this compiler 
and use its tiny language to implement a bigger language.
This process ultimately produced a verified compiler in both source form 
and assembly language form, with a proof of their equivalence, 
as well as &lt;a href=&quot;https://doi.org/10.1145/2364527.2364545&quot;&gt;verified extraction&lt;/a&gt; from higher-order logic to ML.&lt;/p&gt;

&lt;p&gt;The end of the decade also saw impressive results in the formalisation of mathematics:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://rdcu.be/eSZwv&quot;&gt;Gödel second incompleteness theorem&lt;/a&gt;, by yours truly, in Isabelle/HOL&lt;/li&gt;
  &lt;li&gt;the &lt;a href=&quot;https://arxiv.org/abs/1405.7012&quot;&gt;Central Limit Theorem&lt;/a&gt;, by Avigad et al., ditto&lt;/li&gt;
  &lt;li&gt;the &lt;a href=&quot;https://github.com/flyspeck/flyspeck&quot;&gt;Flyspeck&lt;/a&gt; project, by Hales et al., in Isabelle/HOL and HOL Light&lt;/li&gt;
  &lt;li&gt;the &lt;a href=&quot;https://doi.org/10.1145/2480359.2429071&quot;&gt;odd order theorem&lt;/a&gt;, in Rocq&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without going into details here, each of these was an ambitious proof, combining in various ways deep mathematics, intricate technicalities and sheer bulk.
Our community was proud of our achievements.
We were no longer a joke, but what exactly we were good for?&lt;/p&gt;

&lt;h3 id=&quot;20152025-breaking-through&quot;&gt;2015–2025: Breaking through&lt;/h3&gt;

&lt;p&gt;This period brought something astonishing: 
acceptance of proof assistants by many mainstream mathematicians.
I mostly recall mathematicians regardeding computers 
with something close to contempt. 
Even some logicians regarded formalised mathematics as impossible, 
somehow fixating on Gödel’s incompleteness or that notorious proof of 1+1=2 on page 360.
Regarding my work formalising big chunks of ZF theory, 
someone commented “only for finite sets obviously”.&lt;/p&gt;

&lt;p&gt;My EU-funded &lt;a href=&quot;https://www.cl.cam.ac.uk/~lp15/Grants/Alexandria/&quot;&gt;ALEXANDRIA&lt;/a&gt; project started in 2017. 
My team formalised more advanced and deep mathematics 
than I ever imagined to be possible, using Isabelle/HOL.
(I have told this story in an &lt;a href=&quot;/2023/08/31/ALEXANDRIA_finished.html&quot;&gt;earlier blogpost&lt;/a&gt;.)
But ALEXANDRIA alone would not have had much of an impact on mathematical practice.
What made a difference was &lt;a href=&quot;https://xenaproject.wordpress.com/what-is-the-xena-project/&quot;&gt;Kevin Buzzard&lt;/a&gt; and his enthusiastic, tireless promotion of the idea of formalising mathematics 
in &lt;a href=&quot;https://lean-lang.org&quot;&gt;Lean&lt;/a&gt;.
He recruited a veritable army.
I got the idea of blogging from him, but my blog has not had the same impact. Where are you guys?&lt;/p&gt;

&lt;p&gt;In 2022, for the first time ever, machine assistance 
was &lt;a href=&quot;https://leanprover-community.github.io/blog/posts/lte-final/&quot;&gt;used to confirm&lt;/a&gt; 
brand-new mathematics that a Fields Medallist had concerns about.
Mathematicians will for the most part continue to work the way they always have done, 
but proof assistants are getting better and better, 
and they will encroach more and more on the everyday practice of mathematics.&lt;/p&gt;

&lt;p&gt;Meanwhile, Isabelle continued to be useful for verification.
I was amazed to hear that that the systems group here in the Computer Lab 
had completed a &lt;a href=&quot;https://doi.org/10.1145/3133933&quot;&gt;major verification&lt;/a&gt; using Isabelle/HOL.
The tradition is for systems people to despise verification tools 
for sweeping aside ugly things like overflow and floating point errors, even though they no longer do.
Besides, a research tool like Isabelle is only used by its own developer and his students.
Times were changing.&lt;/p&gt;

&lt;p&gt;Isabelle is also one of the several proof assistants involved 
with &lt;a href=&quot;https://www.cl.cam.ac.uk/research/security/ctsrd/cheri/&quot;&gt;CHERI&lt;/a&gt;, a large-scale project
reviving the old idea of &lt;em&gt;capabilities&lt;/em&gt; to ensure security at the hardware level.
CHERI has produced numerous publications, some of which 
(for example &lt;a href=&quot;https://doi.org/10.1007/978-3-030-99336-8_7&quot;&gt;this one&lt;/a&gt; 
and &lt;a href=&quot;https://doi.org/10.1109/SP40000.2020.00055&quot;&gt;that one&lt;/a&gt;) describe very large proofs.
These concern the design and implementation of novel computer architectures 
with fine-grained memory protection, 
and a design process with formal verification at its heart.&lt;/p&gt;

&lt;p&gt;Isabelle has also contributed to the design of &lt;a href=&quot;https://webassembly.org&quot;&gt;WebAssembly&lt;/a&gt;, 
a relatively new platform for web applications.
By subjecting the WebAssembly specification to &lt;a href=&quot;https://doi.org/10.1145/3167082&quot;&gt;formal scrutiny&lt;/a&gt;, 
Conrad Watt was able to identify a number of issues in time for them to be fixed.&lt;/p&gt;

&lt;p&gt;Finally, I’d like to mention this announcement (4 December 2025) by Dominic Mulligan of Amazon Web Services (AWS):&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Over three years, lots of hard work, and 260,000 lines of Isabelle/HOL code later, the Nitro Isolation Engine (NIE) &lt;a href=&quot;https://www.aboutamazon.com/news/aws/aws-graviton-5-cpu-amazon-ec2&quot;&gt;is finally announced&lt;/a&gt; alongside Graviton5.&lt;/p&gt;

  &lt;p&gt;Working with our colleagues in EC2, Annapurna, and AWS AppSec, we have been working to rearchitect the Nitro system for Graviton5+ instances around a small, trusted separation kernel. Written from scratch in Rust, we have additionally specified the behaviour of a core subset of the Nitro Isolation Engine kernel, verified that the implementation meets this specification, and additionally proved deep security properties—confidentiality and integrity—of the implementation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I am biased, since I’ve been working with AWS on &lt;a href=&quot;https://www.youtube.com/watch?v=hqqKi3E-oG8&quot;&gt;this exact project&lt;/a&gt;, but it’s a big deal.
AWS has been using formal verification tools for a considerable time.
A notable earlier accomplishment was verify tricky but efficient algorithms using HOL Light,
&lt;a href=&quot;https://www.amazon.science/blog/formal-verification-makes-rsa-faster-and-faster-to-deploy&quot;&gt;speeding up&lt;/a&gt;
RSA encryption by a massive factor.&lt;/p&gt;

&lt;h3 id=&quot;20252035-becoming-ordinary&quot;&gt;2025–2035 Becoming ordinary&lt;/h3&gt;

&lt;p&gt;A couple of months ago, Apple announced new models in their iPhone range,
but no crowds formed around Apple Stores.
They once did: the iPhone was once regarded as revolutionary.
Now, smartphones are a commodity, which is the final stage of a new technology.
Formal verification is not ordinary yet. 
But it’s coming: more and more software will be seen as too important to develop any other way, 
as is already the case for hardware.&lt;/p&gt;

&lt;h3 id=&quot;postscript&quot;&gt;Postscript&lt;/h3&gt;

&lt;p&gt;I am well aware that there is much outstanding work adjacent to that
described here, e.g. using other interactive tools, such as Nqthm and ACL2,
PVS and Agda, and much else using Rocq. There have been amazing advances 
in the broader theorem proving world, also in model checking,
SAT/SMT solving and their applications to extended static checking of software.
I have related what I personally know.
And remember, the point of this post is not (simply) to boast 
but to demonstrate the progress of our research community, 
so the more achievements the better. Feel free to add some in the comments!&lt;/p&gt;

&lt;p&gt;This post does not prove anything about other fields of science, 
such as solid-state physics, molecular biology or mathematics.
But it’s fair to assume that such fields have not been idle either. 
People have proved Fermat’s Last Theorem and the Poincaré conjecture, 
and settled more obscure questions such as the projective plane of order 10.
People have located the remains of King Richard III, who died in 1485, 
excavating and positively identifying the body by its DNA.
People have linked a piece of bloody cloth to Adolf Hitler and diagnosed  that he had a specific genetic condition.
The immensely complex James Webb Space Telescope
was successfully deployed;
it is now revealing secrets about the early Universe.&lt;/p&gt;

&lt;p&gt;Sometimes I wonder about the motives of those who claim that science is moribund. 
Do they have political aims, or just unrealistic expectations?
Were they expecting time travel or some sort of warp drive?
People need to remember that movies are fiction.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Cool things were also done in &lt;a href=&quot;https://era.ed.ac.uk/handle/1842/504&quot;&gt;LEGO&lt;/a&gt;, another type theory proof assistant, but sadly it soon fell by the wayside. And they were sued by some crazy guys from Billund. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;In fact, the correctness of CompCert is delicate for &lt;a href=&quot;https://doi.org/10.1007/978-3-030-99336-8_8&quot;&gt;a number of reasons&lt;/a&gt;. &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
				<pubDate>Fri, 05 Dec 2025 00:00:00 +0000</pubDate>
				<link>https://lawrencecpaulson.github.io//2025/12/05/History_of_Proof_Assistants.html</link>
				<guid isPermaLink="true">https://lawrencecpaulson.github.io//2025/12/05/History_of_Proof_Assistants.html</guid>
			</item>
		
			<item>
				<title>Set theory with types</title>
				<description>&lt;p&gt;It is known that mathematics is heavily reliant on set theory,
but no one can agree on what set theory is.
Many people today understand that we have 
a &lt;a href=&quot;/2022/03/16/Types_vs_Sets.html&quot;&gt;choice between set theory and type theory&lt;/a&gt;, 
but they don’t know what type theory is either.
Many think that type theory refers to 
some sort of dependent type theory, as found in Lean or Agda,
while everything else is set theory.
But prior to 1980 or so, “type theory” generally referred 
to higher-order logic and related systems.
In 1973, NG de Bruijn wrote a paper called 
&lt;a href=&quot;https://automath.win.tue.nl/archive/pdf/aut032.pdf&quot;&gt;“Set Theory with Type Restrictions”&lt;/a&gt;.
His discussion of set theory with types was intended as motivation for the
&lt;a href=&quot;https://lawrencecpaulson.github.io/tag/AUTOMATH&quot;&gt;AUTOMATH&lt;/a&gt; language,
a dependent type theory.
His thoughts are fascinating and pertinent today.&lt;/p&gt;

&lt;h3 id=&quot;set-theory-according-to-de-bruijn&quot;&gt;Set theory according to de Bruijn&lt;/h3&gt;

&lt;p&gt;De Bruijn begins “it has been believed throughout this century that set theory 
is the basis of all mathematics.” He specifies this as “Cantor set theory”,
or Zermelo–Fraenkel (ZF).
And indeed a lot of people continue to insist on this ZF foundation.
Paradoxically, mathematicians (who are the ones with skin in the game)
are generally the least interested in the technicalities of set theory:
actual set theorists are scarce, and the questions they study
seldom have a direct impact on other branches of mathematics.
De Bruijn continues:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;It seems, however that there is a revolt. Some people have begun to dislike the doctrine “everything is a set”, just at the moment that educational modernizers have pushed set theory even into kindergarten. It is not unthinkable that this educational innovation is one of the things that make others try to get rid of set theory’s grip for absolute power.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I was one of those who was taught a tiny bit of set theory in school, 
when I was something like eight years old.
I don’t think it went beyond unions and intersections of two sets.
They didn’t even cover &lt;a href=&quot;https://en.wikipedia.org/wiki/Aronszajn_tree&quot;&gt;Aronszajn trees&lt;/a&gt;.
I don’t know who was behind this educational trend, 
but intersections and unions are useful concepts even in everyday life.
&lt;a href=&quot;https://www.cam.ac.uk/news/professor-roger-needham-1935-2003&quot;&gt;Roger Needham&lt;/a&gt; 
liked to describe unrealistic expectations as 
“an elaborate description of the empty set”;
people need to be able to understand such remarks.&lt;/p&gt;

&lt;p&gt;De Briujn’s chief objection to ZF set theory comes from “the weird idea that &lt;em&gt;everything is set&lt;/em&gt;”:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;In our mathematical culture we have learned to keep things apart.
If we have a rational number and a set of points in the Euclidean plane, we cannot even
imagine what it means to form the intersection. The idea that both might have been coded
in ZF with a coding so crazy that the intersection is &lt;em&gt;not empty&lt;/em&gt; seems to be ridiculous.&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;He also mentions the possibility of writing $x\in x$,
which seems nonsensical and gave us Russell’s paradox.
Also objectionable to many are the numerous coding tricks employed,
where the ordered pair $(x,y)$ becomes $\{\{x\},\{x,y\}\}$
and the natural number $n$ becomes $\{0, \ldots, n-1\}$.
He continues:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The natural, intuitive way to think of a set, is to collect things that belong to a class or type given beforehand. In this way one can try to get theories that stay quite close to their interpretations, that exclude $x\in x$ and are yet rich enough for everyday mathematics.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I like this statement, because it is precisely how sets are used in Isabelle/HOL
and how they could be used (but seldom are) in the HOL family of proof assistants.&lt;/p&gt;

&lt;p&gt;I have my own objection to Zermelo–Fraenkel set theory:
it is much, much too large for any imaginable purpose.
It bugs me that people are continuing to grasp for even stronger systems,
notably Tarski–Grothendieck set theory. Towards the end of his paper, de Bruijn says&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The world where we have $\mathbb{N}$, $\mathbb{N}^\mathbb{N}$, $\mathbb{N}^{\mathbb{N}^\mathbb{N}}, \ldots$, but where [the union of all those sets] is “inaccessible”, is a world most mathematicians will doubtlessly find big enough to live in. For those who want to have a bigger world…, there is a simple way out: they just take a type SET and provide it with Zermelo–Fraenkel axioms. If they want to have the picture complete, they will not find it hard to embed the types $\mathbb{N}$, $\mathbb{N}^\mathbb{N}$,  $\mathbb{N}^{\mathbb{N}^\mathbb{N}}, \ldots$ into a small portion of their paradise.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The context of this remark is that AUTOMATH, by virtue of its built-in
general product, allows 
$\mathbb{N}$, $\mathbb{N}^\mathbb{N}$,  $\mathbb{N}^{\mathbb{N}^\mathbb{N}}, \ldots$ 
to be constructed while having no way to form their “union”
because it provides no way of indexing over types.
I am impressed that de Bruijn already perceived back in 1973 that such a weak system
was strong enough for most mathematics.
I came to this conclusion only recently, 
after a series of formalisation experiments using Isabelle and higher-order logic.
We can easily use the convenient language of sets in higher-order logic,
and we also have the option to “take a type SET and provide it with Zermelo–Fraenkel axioms”.&lt;/p&gt;

&lt;h3 id=&quot;sets-in-higher-order-logic&quot;&gt;Sets in higher-order logic&lt;/h3&gt;

&lt;p&gt;Higher-order logic is descended from the mysterious, 
never-properly-formalised system of
&lt;a href=&quot;https://plato.stanford.edu/entries/principia-mathematica/&quot;&gt;Principia Mathematica&lt;/a&gt; (PM).
Whitehead and Russell wrote extensively about &lt;em&gt;classes&lt;/em&gt;,
which were clearly the same thing as typed sets,
though PM was never explicit about what its type system actually was.
Higher-order logic as &lt;a href=&quot;https://plato.stanford.edu/entries/type-theory-church/&quot;&gt;formalised by Church&lt;/a&gt;
is PM done right.
A set is nothing but a boolean-valued function, exactly the same thing as a logical predicate, and the phrase “predicate sets”
is fairly common in the &lt;a href=&quot;https://rdcu.be/eQa72&quot;&gt;literature of the HOL proof assistant&lt;/a&gt;.
Nevertheless, we think about sets and predicates differently, 
even in the trivial case of unions and intersections.
Often I have looked at an HOL Light proof and seen a prediate $Q(x)$
defined by $\exists y. P(y) \land x = f(y)$,
which is simply the image under the function $f$ of a set.&lt;/p&gt;

&lt;p&gt;Early versions of Isabelle/HOL maintained separate types for sets and predicates.
At some point about 20 years ago, somebody had the idea of abolishing the distinction,
presumably to avoid some duplication. This change persisted for a couple of releases
before being laboriously reversed. Sets and predicates are simply not the same.&lt;/p&gt;

&lt;h3 id=&quot;the-elements-of-typed-set-theory&quot;&gt;The elements of typed set theory&lt;/h3&gt;

&lt;p&gt;Typed set theory has everything that you would expect, only typed.
As de Bruijn would wish, it excludes $x\in x$:
you can write $x\in A$ only if the types agree.
That means, if $x$ has type $\tau$ then $A$ has type $\tau\,\texttt{set}$, 
which is also the type of the &lt;em&gt;comprehension&lt;/em&gt; $\{x.\,P(x)\}$ 
if $x$ has type $\tau$. Union, intersection and difference combine two sets of the same type in the obvious way.
We have the universal set and therefore set complement
because our sets are typed:
we have the set of all integers, say,
or of all sets of integers, but never the set of &lt;em&gt;all&lt;/em&gt; sets.
The power set operator 
(which denotes the set of all subsets of its argument)
takes type $\tau\,\texttt{set}$ to type $(\tau\,\texttt{set})\,\texttt{set}$.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;image&lt;/em&gt; operator is the set-theoretic version of the “apply to all” operator that’s called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt; in programming languages 
from &lt;a href=&quot;https://doi.org/10.1145/3386336&quot;&gt;Standard ML&lt;/a&gt; to Perl, except in LISP where it’s called &lt;a href=&quot;https://www.gnu.org/software/emacs/manual/html_node/elisp/Mapping-Functions.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MAPCAR&lt;/code&gt;&lt;/a&gt;; 
their &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MAP&lt;/code&gt; does something weird. 
In Isabelle/HOL, the image of a set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A&lt;/code&gt; under the function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f&lt;/code&gt; is written &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f ` A&lt;/code&gt; and please accept my apologies for a syntax influenced by PM.
But mathematicians write $f(A)$ for the set of all $f(x)$ 
for $x\in A$, treating $A$ as a set because of its capital letter,
which would never do.
The &lt;em&gt;inverse image&lt;/em&gt; is written &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f -` A&lt;/code&gt; and denotes the set of all $x$ 
such that $f(x)\in A$.
Both operators are typed in the obvious way.&lt;/p&gt;

&lt;p&gt;This brings us to something crucial: the function space
$A\to B$ and its generalisation to the indexed product, $\prod_{x\in A}\,B(x)$.
The latter was called a “dependent function space” 
by Robert Constable but is called the “dependent product”
by people who never bothered to read Constable’s papers.
It has been around for more than a century
due to its close association with the axiom of choice,
which states that $\prod_{x\in A}\,B(x)$ is nonempty provided
$B(x)$ is nonempty for all $x\in A$.
In typed set theory, we often need to talk about 
the set of all functions that have domain $A$ and codomain $B$,
and occasionally the greater precision of the indexed product is helpful.
Both are trivial to define using set comprehension;
in fact, $f\in A\to B$ if and only if $f(A)\subseteq B$.
There is a complication concerning function extensionality,
which I will not discuss here.
Another complication is that the inverse image 
involving a function in $A\to B$ is generally expected to be a
subset of $A$; the Isabelle/HOL inverse image operator does not 
and cannot accomplish that.&lt;/p&gt;

&lt;p&gt;Analogously, we need the binary product space $A\times B$. 
Its generalisation $\sum_{x\in A}\,B(x)$,
the indexed sum (Constable’s “dependent product”), 
is not especially important but has its uses.
Both are again trivial to define using set comprehension.
As in type theory, the “non-dependent”
versions $A\to B$ and $A\times B$ are not even defined separately
but are simply degenerate cases of the full versions
when $B$ does not depend on $x$.&lt;/p&gt;

&lt;p&gt;If $f\in A\to B$ then we may want to know whether $f$ is an &lt;em&gt;injective&lt;/em&gt; on the set $A$ or
whether it is &lt;em&gt;surjective&lt;/em&gt; (the image $f(A)$ equals $B$).
If $f$ is both then it is a &lt;em&gt;bijection&lt;/em&gt; between the two sets.
These properties also can give us an indication of the relative sizes of $A$ and $B$:
if $f$ is an injection then $A$ is “smaller” than $B$ 
(written $A\precsim B$ or $A\prec B$ if $A$ is strictly smaller). 
Then we can also talk about &lt;em&gt;countable&lt;/em&gt; sets.
Exhibiting a bijection between two sets shows that they are &lt;em&gt;equinumerous&lt;/em&gt; 
and is often the easiest way 
to show that they have the same &lt;em&gt;cardinality&lt;/em&gt;.
In the basic Isabelle/HOL library, the cardinality function for sets
returns a natural number, so it is only useful for finite sets,
but we can do much better if necessary.&lt;/p&gt;

&lt;h3 id=&quot;incorporating-all-of-zermelofraenkel-set-theory&quot;&gt;Incorporating all of Zermelo–Fraenkel set theory&lt;/h3&gt;

&lt;p&gt;Typed set theory, as sketched above, meets de Bruijn’s desiderata.
It is also simpler and more intuitive than AUTOMATH,
and can express vast swathes of mathematics in a natural manner.
But, for better or worse, set-theoretic notions such as transfinite ordinals and cardinals
sometimes &lt;a href=&quot;https://rdcu.be/cWkY5&quot;&gt;pop up in odd places&lt;/a&gt;.
ZF set theory becomes inescapable once its very language 
finds its way into your theorem statement.
I have &lt;a href=&quot;/2022/04/06/ZFC_in_HOL.html&quot;&gt;already written&lt;/a&gt; on how to incorporate
ZF set theory into higher-order logic. It is done exactly as de Bruijn
suggested: by postulating a type of ZF sets and equipping it with all the ZF axioms.&lt;/p&gt;

&lt;p&gt;A possible annoyance with this approach is ending up with two separate mathematical worlds:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;the higher-order logic world, painstakingly constructed by more than 100 Isabelle/HOL theories&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;the vast ZF world, with only eight Isabelle/HOL theories mainly concerned with ordinal and cardinal numbers, everything else existing only as possible consequences of the ZF axioms&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As I &lt;a href=&quot;/2022/04/06/ZFC_in_HOL.html&quot;&gt;described earlier&lt;/a&gt;, 
the AFP entry &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ZFC_in_HOL&lt;/code&gt; connects the two worlds using Isabelle’s type class system.
It sets up a family of embeddings from the standard Isabelle/HOL type constructors
to suitable ZF analogues. ZF thereby gets things like 
the set of real numbers for free: we don’t have to construct it all over again.
Summarising the earlier blog post, it’s done by&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;defining the type class &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;embeddable&lt;/code&gt; of types that can be embedded into the ZF universe&lt;/li&gt;
  &lt;li&gt;defining the type class &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;small&lt;/code&gt; of types that can be embedded into some ZF set&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An Isabelle library defines a type class of countable types
and proves many basic types to be countable or to preserve countability.
These include &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nat&lt;/code&gt;  (the natural numbers) and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rat&lt;/code&gt; (the rational numbers). 
Moreover, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;countable&lt;/code&gt; is a subclass of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;small&lt;/code&gt;, which is a subclass of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;embeddable&lt;/code&gt;. 
It follows immediately that all those basic types are small.
Moreover, the function space type constructor preserves smallness.
To show that there is a ZF set corresponding to the Isabelle/HOL type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;real&lt;/code&gt;,
we need to show that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;real&lt;/code&gt; belongs to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;small&lt;/code&gt;, 
which is trivial because each real number is represented by a set of functions
from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nat&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rat&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;a-simpler-way-to-get-some-set-theory&quot;&gt;A simpler way to get some set theory&lt;/h3&gt;

&lt;p&gt;De Bruijn objects to the principle that “everything is a set”, 
but it comes in handy when you are trying to define spaces.
Given any two sets $A$ and $B$, you can always construct their 
unions and intersections, the product $A\times B$, function space $A\to B$, 
also the disjoint sum $A+B$, enumerations like $\{A,B\}$,
the indexed sum and product and much more.
This sort of flexibility comes in handy when defining the semantics
of a programming language, where variables can range over a variety of types.
It also comes in handy when talking about finite state machines,
where different ways of combining machines require analogous ways 
of combining sets of machine states.
If you are in a typed world like higher-order logic, 
you may be tempted to just use the natural numbers 
along with some encoding of the necessary structures. But that sucks.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://www.isa-afp.org/entries/HereditarilyFinite.html&quot;&gt;&lt;em&gt;hereditarily finite sets&lt;/em&gt;&lt;/a&gt; (type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hf&lt;/code&gt;)
give us everything that ZF does, with the big exception of infinite sets.
Hereditarily finite sets are finite all the way down.
Finitary constructions such as integers, rationals, 
and obvious data structures like pairs and lists are easily represented.
But we have no real numbers (only floating point) 
and cannot use infinite equivalence classes either.
Still, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hf&lt;/code&gt; has everything we need for modelling possible data in a programming language 
or state spaces in the world of &lt;a href=&quot;https://arxiv.org/pdf/1505.01662&quot;&gt;finite state machines&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The set of all hereditarily finite sets is countable, 
and they &lt;a href=&quot;/2022/02/23/Hereditarily_Finite.html&quot;&gt;map naturally to the natural numbers&lt;/a&gt;.
That means, if you use type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hf&lt;/code&gt;, you are essentially using the natural numbers,
but the structural embeddings are hidden 
and you get to use those beloved set-theoretic constructions.
And &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hf&lt;/code&gt; is definable in higher-order logic without additional axioms.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Addendum 2025-11-22&lt;/em&gt;: I wrote above that the technicalities of set theory seldom mattered to anybody else, and on the same day, &lt;em&gt;Quanta Magazine&lt;/em&gt; published &lt;a href=&quot;https://www.quantamagazine.org/a-new-bridge-links-the-strange-math-of-infinity-to-computer-science-20251121/&quot;&gt;this article&lt;/a&gt;!&lt;/p&gt;
&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;This remark comes from a related paper by de Bruijn: &lt;a href=&quot;https://research.tue.nl/en/publications/on-the-roles-of-types-in-mathematics/&quot;&gt;On the roles of types in mathematics&lt;/a&gt; &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
				<pubDate>Fri, 21 Nov 2025 00:00:00 +0000</pubDate>
				<link>https://lawrencecpaulson.github.io//2025/11/21/Typed_Set_Theory.html</link>
				<guid isPermaLink="true">https://lawrencecpaulson.github.io//2025/11/21/Typed_Set_Theory.html</guid>
			</item>
		
			<item>
				<title>&quot;Why don&apos;t you use dependent types?&quot;</title>
				<description>&lt;p&gt;To be fair, nobody asks me this exact question.
But people have regularly asked why Isabelle dispenses with proof objects.
The two questions are essentially the same, 
because proof objects are intrinsic to all the usual type theories.
They are also completely unnecessary and a huge waste of space.
As described in an &lt;a href=&quot;/2022/01/05/LCF.html&quot;&gt;earlier post&lt;/a&gt;,
type checking in the &lt;em&gt;implementation language&lt;/em&gt; (rather than in the logic)
can ensure that only legitimate proof steps are executed.
Robin Milner had this fundamental insight 50 years ago,
giving us the LCF architecture with its proof kernel.
But the best answer to the original question is simply this: 
I did use dependent types, for years.&lt;/p&gt;

&lt;h3 id=&quot;my-time-with-automath&quot;&gt;My time with AUTOMATH&lt;/h3&gt;

&lt;p&gt;I was lucky enough to get some personal time with N G de Bruijn
when he came to Caltech in 1977 to lecture about
&lt;a href=&quot;/2021/11/03/AUTOMATH.html&quot;&gt;AUTOMATH&lt;/a&gt;.
I never actually got to use this system.
Back then, researchers used the nascent Internet (the ARPAnet)
not to download software so much as 
to run software directly on the host computer, 
since most software was not portable.
But Eindhoven University was not on the ARPAnet,
and AUTOMATH was configured to run on 
&lt;a href=&quot;https://automath.win.tue.nl/archive/pdf/aut034.pdf&quot;&gt;a computer we did not have&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Until September 1973, the computer was the Electrologica X8, after that
Burroughs 6700. In both cases the available multiprogranming systems
required the use of ALGOL 60.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I did however read many of the research reports, including 
the &lt;a href=&quot;https://automath.win.tue.nl/archive/pdf/aut046.pdf&quot;&gt;PhD dissertation&lt;/a&gt; by LS Jutting,
where he presents his translation 
of Landau’s text &lt;em&gt;Grundlagen der Analysis&lt;/em&gt; (described &lt;a href=&quot;/2025/10/15/Proofs-trivial.html&quot;&gt;last time&lt;/a&gt;)
from German into AUTOMATH.
It is no coincidence that many of my papers, from the
&lt;a href=&quot;https://doi.org/10.1016/0167-6423(85)90009-7&quot;&gt;earliest&lt;/a&gt;
to the &lt;a href=&quot;https://doi.org/10.4230/LIPIcs.ITP.2025.18&quot;&gt;latest&lt;/a&gt;,
copied the idea of formalising a text
and attempting to be faithful to it, if possible line by line.&lt;/p&gt;

&lt;p&gt;As an aside, note that while AUTOMATH was a system of dependent types,
it did not embody the 
&lt;a href=&quot;/2023/08/23/Propositions_as_Types.html&quot;&gt;Curry–Howard correspondence&lt;/a&gt;
(sometimes wrongly called the Curry–Howard–de Bruijn correspondence).
That correspondence involves having a type theory strong enough
to represent the predicate calculus directly in the form of types.
In AUTOMATH you had to introduce the symbols and inference rules 
of your desired calculus in the form of axioms, much as you do with Isabelle.
In short, AUTOMATH was a &lt;a href=&quot;https://pure.tue.nl/ws/files/1892191/597622.pdf&quot;&gt;logical framework&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;like a big restaurant that serves all sorts of food: vegetarian, kosher, or anything else the customer wants&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;De Bruijn
&lt;a href=&quot;https://pure.tue.nl/ws/portalfiles/portal/4428179/597611.pdf&quot;&gt;did not approve&lt;/a&gt; 
of the increasingly powerful type theories being developed in the 1990s.
AUTOMATH was a weak language, 
a form of λ-calculus including a general product construction just
powerful enough to express the inference rules of a variety of formalisms
and to make simple definitions, again clearly the inspiration for Isabelle.
Isabelle aims to be &lt;a href=&quot;https://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-130.html&quot;&gt;&lt;em&gt;generic&lt;/em&gt;&lt;/a&gt;, like the big AUTOMATH restaurant.
Only these days everybody prefers the same cuisine,
higher-order logic, so Isabelle/HOL has become dominant.
Unfortunately, I last spoke to Dick (as he was known to friends)
when I was putting all my effort into Isabelle/ZF.
He simply loathed set theory and saw mathematics as essentially typed.
He never lived to see the enormous amount of advanced mathematics
that would be formalised using types in Isabelle/HOL.&lt;/p&gt;

&lt;p&gt;I annoyed him in another way. I kept asking,
AUTOMATH looks natural, but how do we know that it is right?
He eventually sent me a 300 page volume entitled
&lt;a href=&quot;https://automath.win.tue.nl/archive/pdf/aut073.pdf&quot;&gt;The Language Theory of Automath&lt;/a&gt;.
It describes AUTOMATH’s formal properties such as 
strong normalisation and Church–Rosser properties,
but this was not the answer I wanted at all.
I got that answer for a quite different type theory.&lt;/p&gt;

&lt;h3 id=&quot;martin-löf-type-theory&quot;&gt;Martin-Löf type theory&lt;/h3&gt;

&lt;p&gt;In response to kind invitations from Bengt Nordström and Kent Petersson,
I paid a number of visits to Chalmers University in Gothenburg
to learn about Martin-Löf type theory.
I was particularly impressed by its promise 
of a systematic and formal approach to program synthesis.
I had already encountered &lt;a href=&quot;/2021/11/24/Intuitionism.html&quot;&gt;intuitionism&lt;/a&gt;
through a course on the philosophy of mathematics at Stanford University,
as I recall taught by &lt;a href=&quot;https://www.pet.cam.ac.uk/news/professor-ian-macdougall-hacking-1936-2023&quot;&gt;Ian Hacking&lt;/a&gt;.
The “rightness” of Martin-Löf type theory was obvious, 
because it directly embodied the principles of intuition truth
as outlined by Heyting: for example, that
a proof of $A\land B$ consists of a proof of $A$ paired with a proof of $B$.&lt;/p&gt;

&lt;p&gt;I devoted several years of research to Martin-Löf type theory.
This included a whole year of intricate hand derivations to produce a 
&lt;a href=&quot;https://doi.org/10.1016/S0747-7171(86)80002-5&quot;&gt;paper&lt;/a&gt; 
that I once thought would be important,
and the &lt;a href=&quot;/2022/07/13/Isabelle_influences.html&quot;&gt;very first version&lt;/a&gt; 
of Isabelle.
Yes: Isabelle began as an implementation of Martin-Löf type theory,
which is &lt;a href=&quot;/2022/11/30/CTT_in_Isabelle-II.html&quot;&gt;still included&lt;/a&gt; 
in the distribution even today as Isabelle/CTT.
But eventually I got tired of what seemed to me a doctrinaire attitude
bordering on a cult of personality around Per Martin-Löf.
The sudden switch to intensional equality 
(everyone was expected to adopt the new approach) wrecked most of my work.
Screw that.&lt;/p&gt;

&lt;p&gt;You might ask, what about the calculus of constructions,
which arose during that time and eventually gave us Rocq and Lean?
(Not to mention &lt;a href=&quot;https://www.lfcs.inf.ed.ac.uk/reports/92/ECS-LFCS-92-211/&quot;&gt;LEGO&lt;/a&gt;.)
To me they raised, and continue to raise, the same question I had put to de Bruijn.
Gérard Huet said something like “it is nothing but function application”,
which did not convince me.
It’s clear that I am being fussy,&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;
because thousands of people find these formalisms perfectly natural and believable.
But it is also true that the calculus of constructions 
underwent numerous changes over the past four decades.
There seem to be several optional axioms that people sometimes adopt
while attempting to minimise their use, 
like dieters enjoying an occasional croissant.&lt;/p&gt;

&lt;h3 id=&quot;decisions-decisions&quot;&gt;Decisions, decisions&lt;/h3&gt;

&lt;p&gt;We can see all this as an example of the choices we make in research.
People were developing new formalisms. This specific fact was the impetus
for making Isabelle generic in the first place.
But we have to choose whether to spend our time developing formalisms 
or instead to choose a fixed formalism and see how far you can push it.
Both are legitimate research goals.&lt;/p&gt;

&lt;p&gt;For example, already in 1985, Mike Gordon 
was using higher-order logic &lt;a href=&quot;https://doi.org/10.48456/tr-77&quot;&gt;to verify hardware&lt;/a&gt;.
He was not distracted by the idea that some dependent type theory might work better
for &lt;em&gt;n&lt;/em&gt;-bit words and the like.
The formalism that he implemented was essentially the same as the 
&lt;a href=&quot;https://plato.stanford.edu/entries/type-theory-church/&quot;&gt;simple theory of types&lt;/a&gt; 
outlined by Alonzo Church in 1940.
He made verification history using this venerable formalism, 
and John Harrison later found
a clever way to &lt;a href=&quot;https://doi.org/10.1007/11541868_8&quot;&gt;encode the dimension&lt;/a&gt;
of vector types including words.
Isabelle/HOL also implements Church’s simple type theory,
with one extension: &lt;a href=&quot;/2022/03/02/Type_classes.html&quot;&gt;axiomatic type classes&lt;/a&gt;.
Isabelle users also derive much power from the &lt;a href=&quot;https://doi.org/10.1007/s10817-019-09537-9&quot;&gt;locale concept&lt;/a&gt;, 
a kind of module system that lies outside any particular logic.&lt;/p&gt;

&lt;p&gt;During all this time, both Martin-Löf type theory and the calculus of constructions
went through several stages of evolution. It’s remarkable how the Lean community,
by running with a certain version of the calculus,
quickly formalised a &lt;a href=&quot;https://leanprover-community.github.io/mathlib-overview.html&quot;&gt;vast amount of mathematics&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;pushing-higher-order-logic-to-its-limit&quot;&gt;Pushing higher-order logic to its limit&lt;/h3&gt;

&lt;p&gt;I felt exceptionally lucky to win 
&lt;a href=&quot;https://cordis.europa.eu/project/id/742178&quot;&gt;funding from the European Research Council&lt;/a&gt;
for the advanced grant &lt;a href=&quot;/2021/12/08/ALEXANDRIA.html&quot;&gt;ALEXANDRIA&lt;/a&gt;.
When I applied, homotopy type theory was still all the rage,
so &lt;a href=&quot;https://www.cl.cam.ac.uk/~lp15/Grants/Alexandria/Part-B2.pdf&quot;&gt;the proposal&lt;/a&gt;  emphasised Isabelle’s specific advantages: its automation,
its huge libraries and the legibility of its proofs.&lt;/p&gt;

&lt;p&gt;The team started work with enthusiasm.
Nevertheless, I fully expected that we would hit a wall, 
reaching mathematical material
that could not easily be formalised in higher-order logic.
Too much of Isabelle’s analysis library identified topological spaces
with types.
Isabelle’s abstract algebra library was old and crufty.
A number of my research colleagues were convinced
that higher-logic was not adequate for serious mathematics.
But Anthony Bordg took up the challenge, leading a subproject
to &lt;a href=&quot;https://doi.org/10.1080/10586458.2022.2062073&quot;&gt;formalise Grothendieck schemes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For some reason I had a particular fear of the field extension $F[a]$,
which extends the field $F$ with some $a$ postulated to be 
a root of some polynomial over $F$.
(For example, the field of complex numbers is precisely $\mathbb{R}[i]$, 
where $i$ is postulated to be a root of $x^2+1=0$.)
And yet an early outcome of ALEXANDRIA was&lt;a href=&quot;https://rdcu.be/cIK3W&quot;&gt; a proof&lt;/a&gt;,
by Paulo Emílio de Vilhena and Martin Baillon,
that every field admits an algebraically closed extension. 
This was the first proof of that theorem in any proof assistant, 
and its proof involves an infinite series of field extensions.&lt;/p&gt;

&lt;p&gt;We never hit any wall.
As our group went on to formalise 
&lt;a href=&quot;https://www.cl.cam.ac.uk/~lp15/Grants/Alexandria/&quot;&gt;more and more advanced results&lt;/a&gt;,
such as the &lt;a href=&quot;https://doi.org/10.1145/3573105.3575680&quot;&gt;Balog–Szemerédi–Gowers theorem&lt;/a&gt;,
people stopped saying “you can’t formalise mathematics without dependent types”
and switched to saying “dependent types give you nicer proofs”.
But they never proved this claim.&lt;/p&gt;

&lt;p&gt;Now that dependent type theory has attained maturity 
and has an excellent tool in the form of Lean, shall I go back to dependent types?
I am not tempted. The only aspects of Lean that I envy are its huge community and
the &lt;a href=&quot;https://github.com/PatrickMassot/leanblueprint&quot;&gt;Blueprint tool&lt;/a&gt;.
I hear too many complaints about Lean’s performance.
I’ve heard of too many cases where dependent types played badly 
with intensional equality – I sat through an entire talk on this topic – or otherwise made life difficult. 
Quite a few people have told me that 
the secret of dependent types is knowing when &lt;strong&gt;not&lt;/strong&gt; to use them.
And so, to me, they have too much in common 
with Tesla’s &lt;a href=&quot;https://electrek.co/2025/10/29/tesla-full-self-driving-v14-disappoints-with-hallucinations-brake-stabbing-speeding/&quot;&gt;Full Self-Driving&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Addendum&lt;/em&gt;: somebody commented on Hacker News that higher-order logic is too weak 
(in terms of proof-theoretic strength) to formalise post-WWII mathematics.
This is not quite right.
It is true that higher-order logic is much, much weaker than ZF set theory.
But one of the most striking findings of ALEXANDRIA is that this is no obstacle
to doing advanced mathematics, say to formalise Grothendieck schemes.
Such elaborate towers of definitions do not seem to ascend especially high
in the set-theoretic hierarchy. I can only recall a couple of proofs
(&lt;a href=&quot;https://doi.org/10.1080/10586458.2021.1980464&quot;&gt;this one&lt;/a&gt;, 
and &lt;a href=&quot;https://rdcu.be/eNVb6&quot;&gt;that one&lt;/a&gt;) 
that required strengthening higher-order logic with the ZF axioms 
(which is easily done). 
These were theorems that referred to ZF entities in their very statements.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Especially as regards constructive mathematics. To its founders, intuitionism is a philosophy suspicious of language, which it relegates to the purpose of recording and communicating mathematical thoughts. This is the opposite of today’s “constructive mathematics”, which refers the use of a formalism satisfying certain syntactic properties. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
				<pubDate>Sun, 02 Nov 2025 00:00:00 +0000</pubDate>
				<link>https://lawrencecpaulson.github.io//2025/11/02/Why-not-dependent.html</link>
				<guid isPermaLink="true">https://lawrencecpaulson.github.io//2025/11/02/Why-not-dependent.html</guid>
			</item>
		
			<item>
				<title>Most proofs are trivial</title>
				<description>&lt;p&gt;Perhaps I have to begin with an apology. 
I am not asserting that mathematics is trivial,
nor am I belittling students who struggle with elementary exercises.
I know how it feels to be told that a problem I cannot solve is trivial.
Nevertheless, the claim of this post is on the one hand obvious and on the other hand profound.
It suggests new ways of thinking about proof assistants and program verification.
But first, I had better prove my point.&lt;/p&gt;

&lt;h3 id=&quot;discrete-mathematics&quot;&gt;Discrete mathematics&lt;/h3&gt;

&lt;p&gt;Many students hate discrete mathematics and find the problems hard.
Consider for example the powerset identity $\mathcal{P} (A\cap B) = \mathcal{P} (A) \cap \mathcal{P} (B)$.
A typical student will ask, “how do I even begin?”.
But for many of these problems there is just one thing you can do:
some obvious step that doesn’t yield an immediate solution, 
but leads to another obvious step and another and another.
This heuristic is called “following your nose” and it is a great way to prove trivial theorems.
The first obvious step is that two sets are equal if they contain the same elements, so we try&lt;/p&gt;

\[\begin{align*}
X \in \mathcal{P} (A\cap B) \iff X \subseteq A\cap B \iff X \subseteq A \land X \subseteq B \iff X \in \mathcal{P} (A) \cap \mathcal{P} (B). 
\end{align*}\]

&lt;p&gt;Yup, it’s trivial, even if some of those steps could have been expanded out a bit more.&lt;/p&gt;

&lt;p&gt;Many facts of discrete mathematics can be proved by following your nose.
And this gives us a definition of &lt;em&gt;trivial&lt;/em&gt;: 
results that follow more or less mechanically from the definitions.
The &lt;em&gt;fundamental theorem of arithmetic&lt;/em&gt;, which states that every natural number
has a unique factorisation into primes, is a good example of a non-trivial result.
Its proof strays far beyond the definition of a prime number,
relying on Bézout’s identity, 
which relies on Euclid’s algorithm for computing greatest common divisors.&lt;/p&gt;

&lt;h3 id=&quot;whitehead-and-russells-principia-mathematica&quot;&gt;Whitehead and Russell’s &lt;em&gt;Principia Mathematica&lt;/em&gt;&lt;/h3&gt;

&lt;p&gt;In this &lt;a href=&quot;https://plato.stanford.edu/entries/principia-mathematica/&quot;&gt;landmark work&lt;/a&gt;, 
the authors set out to prove that mathematics could be reduced to logic.
And they succeeded, introducing a formal system that, 
after simplification, became what we know today as higher-order logic,
which has recently been used to formalise truly substantial chunks of mathematics.
&lt;em&gt;PM&lt;/em&gt; is notorious for its horrible notation (&lt;a href=&quot;https://archive.org/details/alfred-north-whitehead-bertrand-russel-principia-mathematica.-1/Alfred%20North%20Whitehead%2C%20Bertrand%20Russel%20-%20Principia%20Mathematica.%201/page/107/mode/2up&quot;&gt;take a look!&lt;/a&gt;), 
and also for taking 360 pages to prove that 1+1=2.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;PM&lt;/em&gt; contains only trivial proofs.
As I remarked in an &lt;a href=&quot;/2023/01/11/AI_at_Stanford.html&quot;&gt;earlier post&lt;/a&gt;, 
these assertions were used as exercises in early theorem proving experiments.
Newell and Simon’s heuristic &lt;em&gt;Logic Theorist&lt;/em&gt; proved 38 theorems from the first two chapters in 1958. 
Shortly afterwards, Hao Wang used his knowledge of logic to implement an algorithm that proved
hundreds of theorems from &lt;em&gt;PM&lt;/em&gt; in minutes, on a IBM 704.
It is no disparagement of Wang’s work to say that he demonstrated that &lt;em&gt;PM&lt;/em&gt; presents a list of trivial proofs.
And if you don’t believe me, here is ChatGPT:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;the “abridged edition” of Principia Mathematica (the one that ends at §56) does not contain any “difficult” theorems in the sense of being mathematically deep or challenging; rather, it consists entirely of extremely elementary logical and propositional results, all proved in excruciating detail.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Wang’s level of automation is utterly unattainable – even after seven decades of technological advances – 
for a typical mathematics textbook.&lt;/p&gt;

&lt;h3 id=&quot;foundations-of-analysis&quot;&gt;Foundations of Analysis&lt;/h3&gt;

&lt;p&gt;Edmund Landau’s textbook &lt;em&gt;Grundlagen der Analysis&lt;/em&gt; 
was chosen for the first large-scale experiment
with &lt;a href=&quot;https://lawrencecpaulson.github.io/tag/AUTOMATH&quot;&gt;AUTOMATH&lt;/a&gt; because, as de Bruijn remarked,
it was nicely detailed right through to the end.
Landau’s book develops the complex number system from pure logic, 
so it can be seen as an updated version of &lt;em&gt;PM&lt;/em&gt; without the philosophy.&lt;/p&gt;

&lt;p&gt;Most of Landau’s proofs are trivial.
He introduces the positive natural numbers axiomatically,
including the usual definitions of addition, ordering and multiplication.
The algebraic laws that they enjoy are important mathematical facts, 
but their proofs are all trivial inductions.&lt;/p&gt;

&lt;p&gt;Next, he introduces fractions as equivalence classes 
of pairs of natural numbers.
&lt;a href=&quot;/2022/03/30/Quotienting.html&quot;&gt;Equivalence classes&lt;/a&gt; 
can be a challenge, both for students and for some proof assistants.
However, they are mathematically simpler
than identifying rational numbers with reduced fractions,
which would require a theory of greatest common divisors
and tough proofs to show, for example,
that addition of reduced fractions is associative.
Once you are comfortable with the idea that 
a rational number is an equivalence class,
you can obtain such facts as associativity
with little fuss: they become trivial.
&lt;em&gt;Proofs are easier 
if you use the right mathematical tools&lt;/em&gt;, 
even if they require some sophistication.&lt;/p&gt;

&lt;p&gt;Landau continues by defining Dedekind cuts of rationals,
which yields the positive real numbers.
Theorem 161 on the existence of square roots
is one of the few nontrivial proofs in this chapter.
He proceeds to develop the real and complex number systems straightforwardly.
The “main theorem” of the book is &lt;em&gt;Dedekind’s Fundamental Theorem&lt;/em&gt;,
which expresses the completeness of the reals
and has a detailed proof covering three pages.
But Landau’s style is extremely detailed and even this proof cannot be called hard.&lt;/p&gt;

&lt;p&gt;Landau’s obtains the real numbers 
from the positive reals by a signed-magnitude approach
that complicates proofs with a massive explosion of cases.
Equivalence classes of pairs of positive reals (representing their difference)
is the elegant way to introduce zero and the negative reals.
It’s hard to see why Landau made such an error.&lt;/p&gt;

&lt;p&gt;Few modern textbooks are as detailed as &lt;em&gt;Grundlagen&lt;/em&gt;.
Authors prefer to present only the hard proofs, 
leaving the easy ones (the majority) as exercises.
Don’t be fooled!&lt;/p&gt;

&lt;h3 id=&quot;cantors-theorem&quot;&gt;Cantor’s theorem&lt;/h3&gt;

&lt;p&gt;Cantor’s theorem states that, for any set $A$, 
there exists no surjective function $f : A \to \mathcal{P}(A)$.
The proof, by Russell’s paradox, is easy 
and was first &lt;a href=&quot;https://www.ijcai.org/Proceedings/77-1/Papers/100.pdf&quot;&gt;generated automatically&lt;/a&gt; way back in 1977.
The Isabelle version is just a few lines of Isar text.&lt;/p&gt;

&lt;pre class=&quot;source&quot;&gt;
&lt;span class=&quot;keyword1 command&quot;&gt;theorem&lt;/span&gt; Cantors_theorem&lt;span class=&quot;main&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;∄&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;bound&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;`&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;Pow&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;A&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;proof&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword3 command&quot;&gt;assume&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;∃&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;bound&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;`&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;Pow&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;A&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;keyword3 command&quot;&gt;obtain&lt;/span&gt; &lt;span class=&quot;skolem skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;keyword2 keyword&quot;&gt;where&lt;/span&gt; f&lt;span class=&quot;main&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;`&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;=&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;Pow&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;A&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;keyword1 command&quot;&gt;..&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;var quoted var&quot;&gt;?X&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;bound bound&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∈&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;bound&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∉&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;bound&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;var&quot;&gt;?X&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∈&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;const&quot;&gt;Pow&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;A&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;blast&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;keyword1 command&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;var&quot;&gt;?X&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∈&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;`&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;A&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;simp&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;only&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; f&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;keyword3 command&quot;&gt;obtain&lt;/span&gt; &lt;span class=&quot;skolem skolem&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;keyword2 keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∈&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;A&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;keyword2 keyword&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;=&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;var&quot;&gt;?X&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;blast&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;keyword3 command&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;False&lt;/span&gt; &lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;blast&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;qed&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;Cantor’s theorem is profound and has wide-ranging implications.
It implies that there is no universal set and no greatest cardinal number.
So the &lt;em&gt;theorem&lt;/em&gt; is not trivial, but methinks the &lt;em&gt;proof&lt;/em&gt; kinda is.&lt;/p&gt;

&lt;h3 id=&quot;operational-semantics-of-programming-languages&quot;&gt;Operational semantics of programming languages&lt;/h3&gt;

&lt;p&gt;Since the 1980s, we have had highly sophisticated techniques
for specifying the semantics of programming languages, both
&lt;em&gt;static semantics&lt;/em&gt; such as type checking and name resolution, and
&lt;em&gt;dynamic semantics&lt;/em&gt; or what happens at runtime (including concurrency).
Using such techniques, we can prove that a proposed programming language satisfies
key properties such as 
&lt;em&gt;progress&lt;/em&gt; (a well typed expression can make another step of evaluation)
&lt;em&gt;type preservation&lt;/em&gt; (such an evaluation step will not change its type),
and &lt;em&gt;determinacy&lt;/em&gt; (the next evaluation step is unique).&lt;/p&gt;

&lt;p&gt;The techniques rely on specifying typing, reduction, etc. as relations 
&lt;a href=&quot;/2025/06/09/Inductive_Definitions.html&quot;&gt;defined inductively&lt;/a&gt;),
as I have demonstrated in a &lt;a href=&quot;/2023/03/08/Fun_Semantics.html&quot;&gt;previous blogpost&lt;/a&gt;.
As mentioned in that blogpost, these proofs are simultaneously highly intricate and trivial:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;They are intricate because simply to apply the relevant induction rule
requires pages of formulas, which are almost impossible to write out correctly by hand.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;They are trivial because the properties typically proved hold by design. 
Languages are designed such that the type system makes sense, 
evaluation steps don’t change integers into strings and 
(except for a concurrent language) there is only one possible next step.
The student who has laboriously written out all the cases of an induction
typically discovers that they hold immediately by contradiction or by chasing equalities.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some program properties do have deep and difficult proofs.
The quintessential example is the &lt;a href=&quot;/2024/10/14/Church_Rosser.html&quot;&gt;Church-Rosser theorem&lt;/a&gt;,
which says that different evaluation paths for a particular
λ-term cannot lead to different values.
This obviously desirable property requires a long and complicated case analysis, 
and the first proofs were wrong.&lt;/p&gt;

&lt;h3 id=&quot;program-verification&quot;&gt;Program verification&lt;/h3&gt;

&lt;p&gt;Operational semantics was the topic that led to this blogpost in the first place.
People feel ripped off if they have to struggle to prove something obvious.
And this links to that early critique of program verification by DeMillo, Lipton and Perlis,
which I have &lt;a href=&quot;/2025/03/14/revisiting_demillo.html&quot;&gt;commented on previously&lt;/a&gt;.
What I did not mention was that DeMillo had himself researched program verification.
He presented his work at Yale before Alan Perlis, who asked&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Why does it take 20 pages to prove a program that is obviously correct?&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After that, DeMillo turned against verification with all the zeal of a reformed alcoholic.
Many program proofs are trivial for the same reason that operational semantics proofs are trivial:
because you are verifying something that was designed to satisfy the very property you are proving.
&lt;em&gt;Algorithms&lt;/em&gt; can be subtle and deep, but &lt;em&gt;program code&lt;/em&gt; almost never is.
We should not abandon program proofs, but use verification tools
that automate the tedious aspects.
Where the code implements an algorithm, 
it helps to regard the algorithm and its refinement to executable code
as separate verification tasks.&lt;/p&gt;

&lt;p&gt;DeMillo et al. actually did understand that program proofs were generally trivial.
Recall that for them, &lt;em&gt;social processes&lt;/em&gt; were how mathematical results were confirmed,
and they noted that program proofs were too boring to gain the attention of the mathematical community.
Again we see the distinction between boring program proofs and deep proofs about algorithms,
such as the fascinating &lt;a href=&quot;https://doi.org/10.1145/3703595.3705883&quot;&gt;Burrows–Wheeler transform&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Somehow they confused program proofs – mechanical and tedious to write out, but shallow –
with genuinely deep results. In proof theory, it’s possible to show
that there exist pathological theorems whose proofs are unimaginably large,
hence the authors’ claim that verification would require a computer large enough to fill the observable universe.
That claim is a ridiculous example of worst-case reasoning.
But we do need verification tools that can cope with huge formulas.&lt;/p&gt;

&lt;h3 id=&quot;what-is-the-point-of-proving-trivial-facts&quot;&gt;What is the point of proving trivial facts?&lt;/h3&gt;

&lt;p&gt;One way to address this question is by drawing an analogy with safety checklists in medicine.
The point of asking clinicians to work through a list of tasks they already know they have to do
is that sometimes people forget: there’s plenty of evidence that these much-mocked checklists save lives.
In the same way, checking that a program satisfies its claimed properties 
make sense because programmers make mistakes.
In a formal mathematical development, the trivial proofs are the necessary lead-in
to the headline results one is aiming for.
Proving basic consequences of your definition is also a way to confirm that your definition is correct.
Above all: &lt;em&gt;not every obvious statement is true&lt;/em&gt;.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Donald McKenzie. &lt;em&gt;Mechanising Proof: Computing, Risk, and Trust&lt;/em&gt; (MIT, 2001), p. 201 &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
				<pubDate>Wed, 15 Oct 2025 00:00:00 +0000</pubDate>
				<link>https://lawrencecpaulson.github.io//2025/10/15/Proofs-trivial.html</link>
				<guid isPermaLink="true">https://lawrencecpaulson.github.io//2025/10/15/Proofs-trivial.html</guid>
			</item>
		
			<item>
				<title>Everything you know is wrong</title>
				<description>&lt;p&gt;Among the few advantages of attaining the dizzy age of 70
is the ability to look back on half a century.
Things were great back in 1975.
The Cold War was over, thanks to the détente established by Nixon and Brezhnev.
Most of the world’s population lived under Marxism, and that was not going to change.
The Social Democrats ruled West Germany, and in the UK,
even Rolls-Royce was a state-run enterprise.
The world of fashion discovered pastels, bell bottoms, hot pants and platform shoes:
the very zenith of human culture, styles that would live forever.
Great progress had been made in Artificial Intelligence,
thanks to a relentless focus on symbol processing 
as opposed to discredited, useless neural networks.
Many thought that automatic theorem provers could 
lead the way to what we now call AGI.
Also, watches did not have operating systems.
People knew that clouds were real and that vaccines worked.
Well, a lot can happen in 50 years.&lt;/p&gt;

&lt;h3 id=&quot;artificial-intelligence&quot;&gt;Artificial Intelligence&lt;/h3&gt;

&lt;p&gt;AI is an extreme example of changing research trends.
Already in 1961, a computer program had beat MIT students at calculus problems.
By 1970, Terry Winograd’s &lt;a href=&quot;https://mitmuseum.mit.edu/collections/object/2007.020.027&quot;&gt;SHRDLU&lt;/a&gt; demonstrated something 
remarkably like sentience in its use of English.
The sort of wild predictions made today by AI boosters –
that machines would put everybody out of work and maybe kill us all –
were already being made back then.
Consider the movie &lt;em&gt;2001: A Space Odyssey&lt;/em&gt; (released in 1968),
featuring the smooth-talking but lethal HAL 9000.
Director Stanley Kubrick had chosen MIT’s Marvin Minsky, 
possibly the world’s leading AI researcher,
to be his scientific advisor.
Minsky’s prediction turned out to be way off.&lt;/p&gt;

&lt;p&gt;All AI work in that era was based on manipulating symbols.
The book &lt;em&gt;Perceptrons&lt;/em&gt;, by Minsky and Seymour Papert,
had shown that neural networks could not even learn
such a simple function as exclusive-or: they were worthless.
The remaining debate was whether intelligence was &lt;em&gt;procedural&lt;/em&gt;
(embodied in code) or &lt;em&gt;declarative&lt;/em&gt; (encoded in a symbolic formalism).
SHRDLU was an example of procedural knowledge, 
a great mass of LISP code that no one knew what to do with.
Declarative knowledge might be expressed in first-order logic 
or some other approach to &lt;em&gt;knowledge representation&lt;/em&gt;, 
processed by an automatic theorem prover or other engine.&lt;/p&gt;

&lt;p&gt;Expert systems – &lt;em&gt;Intelligent Knowledge Based Systems&lt;/em&gt; – were attracting widespread attention by 1980.
These contained declarative knowledge in the form of &lt;em&gt;production rules&lt;/em&gt; 
obtained by interrogating human experts in a specific domain. 
For example, &lt;a href=&quot;https://doi.org/10.1016/S0020-7373(78)80049-2&quot;&gt;MYCIN&lt;/a&gt; 
could prescribe antibiotics given a description of the patient’s symptoms.
It could even “explain” its decisions 
based on the production rules involved in the response to a query.&lt;/p&gt;

&lt;p&gt;By the late 1980s, disenchantment with expert systems and other symbolic approaches led to an &lt;a href=&quot;https://dl.acm.org/doi/10.1145/3625833&quot;&gt;“AI Winter”&lt;/a&gt;
that did not really end until neural networks were revived.&lt;/p&gt;

&lt;h3 id=&quot;dpll-versus-resolution-theorem-proving&quot;&gt;DPLL versus resolution theorem proving&lt;/h3&gt;

&lt;p&gt;Interest in automatic theorem proving dates back at least 1956:
&lt;a href=&quot;https://www.historyofinformation.com/detail.php?id=742&quot;&gt;Logic Theorist&lt;/a&gt;
could prove some simple statements from Whitehead and Russell’s
&lt;em&gt;Principia Mathematica&lt;/em&gt;.
Philosopher &lt;a href=&quot;https://lawrencecpaulson.github.io/tag/Hao_Wang&quot;&gt;Hao Wang&lt;/a&gt; and others were excited by the possibility of computers
automating the process of mathematical proof.
One outcome of such work was the 
&lt;a href=&quot;https://doi.org/10.1145/368273.368557&quot;&gt;DPLL procedure&lt;/a&gt; for propositional logic:
the first &lt;em&gt;SAT solver&lt;/em&gt;.
It was quickly superseded by the &lt;a href=&quot;https://doi.org/10.1145/321250.321253&quot;&gt;resolution procedure&lt;/a&gt;,
which worked in the richer formalism of first-order logic.
By the mid 1970s, people were even getting 
&lt;a href=&quot;https://dl.acm.org/doi/abs/10.1016/0004-3702(77)90012-1&quot;&gt;disenchanted with resolution&lt;/a&gt;,
but DPLL still seemed as dead as a doornail.
Attempts to revive DPLL during the 1990s provoked laughter in some,
but nobody is laughing now. 
Resolution has also grown in importance, 
even if nobody thinks it can do robot planning anymore.
&lt;a href=&quot;https://www.usaii.org/ai-insights/what-is-prolog-programming-language-an-overview&quot;&gt;Prolog&lt;/a&gt;, 
a programming language originating in a specialised form of resolution,
attracted enormous interest in the 1980s but had since fallen by the wayside.&lt;/p&gt;

&lt;p&gt;Today, DPLL is the basis of powerful theorem provers 
&lt;a href=&quot;https://doi.org/10.1145/3587692&quot;&gt;based on SMT solvers&lt;/a&gt; 
and used for verifying software.
Both SMT and resolution are used every time an Isabelle user invokes
&lt;a href=&quot;https://www.cl.cam.ac.uk/~lp15/papers/Automation/iwil2010-sledgehammer.pdf&quot;&gt;Sledgehammer&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;specialised-hardware-for-declarative-languages&quot;&gt;Specialised hardware for declarative languages&lt;/h3&gt;

&lt;p&gt;The VLSI revolution that started in the 1970s coincided with the emergence 
of declarative languages such as Prolog 
and &lt;a href=&quot;https://en.wikipedia.org/wiki/ML_(programming_language)&quot;&gt;ML&lt;/a&gt;.
People said that such languages were inefficient only because
they were competing with von Neumann languages running on von Neumann hardware.
But now anyone could put a computer on a chip, 
and a new class of computers designed for declarative languages 
would surely bridge the performance gap.&lt;/p&gt;

&lt;p&gt;Some new hardware designs did emerge, such as
the &lt;a href=&quot;https://dl.acm.org/doi/10.1145/800087.802798&quot;&gt;SKIM machine&lt;/a&gt;
and the &lt;a href=&quot;http://people.cs.bris.ac.uk/~dave/transputer.html&quot;&gt;Transputer&lt;/a&gt;.
The former had support for S, K, I combinator reduction right in its microcode
to execute lazy functional languages fast. The latter was designed for parallel execution,
to be wired together in massive grids for specialised computing tasks.&lt;/p&gt;

&lt;p&gt;The big beast of this era was Japan’s 
&lt;a href=&quot;https://doi.org/10.1016/0167-739X(93)90003-8&quot;&gt;Fifth Generation Computer Systems&lt;/a&gt; project.
It was an attempt to leapfrog western computer technology through new approaches
centred around Prolog, including special hardware.
Similar programmes were launched in other countries, 
notably the UK’s &lt;a href=&quot;https://www.chilton-computing.org.uk/inf/alvey/overview.htm&quot;&gt;Alvey Programme&lt;/a&gt;.
The first &lt;a href=&quot;https://cordis.europa.eu/programme/id/FP1-ESPRIT-1&quot;&gt;ESPRIT&lt;/a&gt; programme 
was Europe’s response.&lt;/p&gt;

&lt;p&gt;This burst of research activity was undoubtedly beneficial to computer science.
Declarative languages such as Haskell emerged,
which over time would exert a profound influence on programming language design.
However, knowledge based systems still reached their dead end,
and all attempts to create novel architectures 
were remorselessly crushed by the Intel steamroller.
An off-the-shelf x86 processor could beat your special chip 
for a fraction of the cost of developing the latter.&lt;/p&gt;

&lt;h3 id=&quot;program-verification-versus-correct-program-synthesis&quot;&gt;Program verification versus correct-program synthesis&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Program verification&lt;/em&gt; is the process of proving correctness properties
of code that has already been written, identifying defects in the process.
For much of my career the very idea has been &lt;a href=&quot;/2025/03/14/revisiting_demillo.html&quot;&gt;heavily criticised&lt;/a&gt;,
mostly as being infeasible&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; but also as being back-to-front.
Begin with the problem specification, people said, 
and work backwards to code that is &lt;em&gt;correct by design&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;One of the foremost proponents of that approach was Edgar W Dijkstra,
a dominant figure right up until his death in 2002.
Already in his 1972 essay “&lt;a href=&quot;https://dl.acm.org/doi/10.5555/1243380.1243381&quot;&gt;Notes on structured programming&lt;/a&gt;”
he set himself the task of printing a table of 1000 prime numbers,
spending 11 pages refining the task “print first thousand prime numbers”
to pseudocode in a language resembling &lt;a href=&quot;https://bitsavers.org/pdf/stanford/cs_techReports/STAN-CS-71-230_Algol_W_Reference_Manual_Feb72.pdf&quot;&gt;Algol W&lt;/a&gt;.
In this example he did not write his specifications in logic,
but in later years his developments became increasingly formal.
One of his bugbears was what he called a &lt;em&gt;rabbit&lt;/em&gt;:
an idea simply “pulled out of a hat” rather than determined by a calculation.
I find it odd to be against having ideas.&lt;/p&gt;

&lt;p&gt;A formal and rather elegant “&lt;a href=&quot;https://doi.org/10.1145/357084.357090&quot;&gt;deductive approach to program synthesis&lt;/a&gt;”
was set forth by Zohar Manna and Richard Waldinger.
They used a tableau style formalism intermingling logical formulas
with code fragments and with a set of inference rules governing the translation
from logic to executable code.
Even more elegant and formal were 
the &lt;a href=&quot;https://www.jstor.org/stable/37448&quot;&gt;constructive type theories&lt;/a&gt; 
outlined by Per Martin-Löf.
By formulating logical &lt;a href=&quot;/2023/08/23/Propositions_as_Types.html&quot;&gt;propositions as types&lt;/a&gt;, such theories
guaranteed that the proof of a given statement yielded a &lt;em&gt;proof object&lt;/em&gt;:
executable code witnessing the claim. The approach required
&lt;a href=&quot;/2022/04/20/Why-constructive.html&quot;&gt;constructive logic&lt;/a&gt;,
but the loss of classical reasoning was a small price to pay
for bug-free code.&lt;/p&gt;

&lt;p&gt;This dream could not work for a number of reasons:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Not all code has the same performance. It is easier to write the code you want and prove it afterwards than to prove a theorem in the precise way that would generate the code you already knew you wanted.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/2025/09/05/All_or_nothing.html&quot;&gt;Specifications are seldom&lt;/a&gt; stable or complete. We know how to extend a program proof to cover additional properties, but we don’t have a deductive synthesis approach that is open to adding further properties later.&lt;/li&gt;
  &lt;li&gt;Many proof objects are computationally &lt;a href=&quot;/2023/08/23/Propositions_as_Types.html&quot;&gt;irrelevant&lt;/a&gt;, but you are confined to constructive reasoning even for those.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the first point, to synthesise a sorting function
we have to prove that every sequence of integers
can be permuted into non-decreasing order.
There is a simple proof by induction: swap the smallest element of the sequence
with the first element, and since the remaining sequence is
shorter by one, the conclusion follows.
The corresponding algorithm is &lt;em&gt;selection sort&lt;/em&gt;, 
which is no good: it takes quadratic time.
To write a proof that corresponds to quicksort,
you have to know quicksort already.
Even in Dijkstra’s 1972 essay, he begins by remarking that
the most efficient way to generate prime numbers is the Sieve of Eratosthenes
and concludes by noting that he has derived exactly that.&lt;/p&gt;

&lt;p&gt;Related to correct-program synthesis was the field of &lt;em&gt;program transformations&lt;/em&gt;, 
explored by &lt;a href=&quot;https://en.wikipedia.org/wiki/Richard_Bird_(computer_scientist)&quot;&gt;Richard Bird&lt;/a&gt;
among others.
The original specification
would be executable (typically written in a functional language) but inefficient.
Your task would be to transform this initial program 
into usable code.
Lots of fascinating research went into program transformations,
but this never looked like an approach that could scale
to thousands of lines.
If we consider sorting again, an executable specification is easily expressed in Prolog:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sort(X, Y) :- permutation(X,Y), ordered(Y).&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This code enumerates every permutation &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Y&lt;/code&gt; of the input &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;X&lt;/code&gt; 
and terminates if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Y&lt;/code&gt; is ordered, otherwise backtracking to get another permutation.
(It would be harder to code in a functional language.) This “specification”
is incomplete because it assumes that such a permutation exists,
which actually must be proved.&lt;/p&gt;

&lt;p&gt;I am one of the many people who were attracted to type theory by the dream 
of deductive program synthesis in the early 1980s.
Every so often, some researcher would attempt to execute 
the proof object they had derived from some interesting theorem.
In almost every case, their extracted code turned out to be all but unusable.
When I checked Wikipedia today, their entry on &lt;a href=&quot;https://en.wikipedia.org/wiki/Program_synthesis&quot;&gt;Program Synthesis&lt;/a&gt;
mentioned the work of Manna and Waldinger but did not contain
a single mention of the words “type” or “constructive”. Dang.&lt;/p&gt;

&lt;h3 id=&quot;postscript&quot;&gt;Postscript&lt;/h3&gt;

&lt;p&gt;If there is a lesson here, it is that almost nothing is settled for certain.
What now is dead may be restored to life, 
what now seems invincible may be laid low,
a decade or two from now.&lt;/p&gt;

&lt;p&gt;I wish I could say that I had taken my own advice, ignored the herd
and struck out boldly on my own.
In fact, I pursued topics that other people found important.
I even found myself bounced into joining 
a Prolog-oriented grant proposal for Alvey that made absolutely no sense.
I devoted years to &lt;a href=&quot;https://rdcu.be/eHmxZ&quot;&gt;writing derivations&lt;/a&gt; 
in Martin-Löf type theory and even coding an implementation 
before falling out with the community’s cultish practices.
The implementation &lt;a href=&quot;/2022/07/13/Isabelle_influences.html&quot;&gt;became Isabelle&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A more impressive role model for a young researcher today 
would be &lt;a href=&quot;/tag/MJC_Gordon&quot;&gt;Mike Gordon&lt;/a&gt;.
He decided that he wanted to verify hardware, something no one else was interested in.
After years of persistent research, he fixed on &lt;a href=&quot;https://lawrencecpaulson.github.io/tag/higher-order_logic&quot;&gt;higher-order logic&lt;/a&gt;
as the best formalism.
He was not tempted by the still evolving dependent type theories,
nor concerned when I mentioned that higher-order logic 
was distained by logicians for its messy metatheory.
Already by 1986 he had achieved his initial milestone
of &lt;a href=&quot;https://doi.org/10.48456/tr-100&quot;&gt;verifying a simple but realistic computer&lt;/a&gt;, 
after which there was no stopping him.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;My dictionary actually illustrates the definition of &lt;em&gt;infeasible&lt;/em&gt; with the sentence “proof that a program works is infeasible unless it is very short”. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
				<pubDate>Sat, 20 Sep 2025 00:00:00 +0000</pubDate>
				<link>https://lawrencecpaulson.github.io//2025/09/20/Wrong.html</link>
				<guid isPermaLink="true">https://lawrencecpaulson.github.io//2025/09/20/Wrong.html</guid>
			</item>
		
			<item>
				<title>Program verification is not all-or-nothing</title>
				<description>&lt;p&gt;There seems to be a common belief that program verification is 
a task that you toil at for ages until one day you see 
that magic word, VERIFIED.
One seminar speaker made this more explicit, presenting testing
as a process where you gain knowledge over time
(illustrated by a graph gently curving upwards)
and verification as a process where you know nothing until the end,
when you know everything
(illustrated by a graph flatlining until the hoped-for triumph).
Where did people get this dumb idea?&lt;/p&gt;

&lt;h3 id=&quot;all-or-nothing-things&quot;&gt;All-or-nothing things&lt;/h3&gt;

&lt;p&gt;Some things really are all-or-nothing.
If you attempt to climb Mount Everest 
and give up a short distance from the summit,
you didn’t make it: all those brutal weeks of high-altitude climbing,
all that danger and hardship, for nothing.
Despite having performed a truly stupendous feat, 
you may not want to talk about how you got only 99% of the way, 
especially if other people climbed past you and summited.&lt;/p&gt;

&lt;p&gt;A similar attitude prevails in mathematics.
Consider &lt;a href=&quot;https://www.maths.cam.ac.uk/features/fermats-last-theorem-history-new-mathematics&quot;&gt;Fermat’s Last Theorem&lt;/a&gt;: 
Andrew Wiles announced his proof
in June 1993, but by September a serious error had been found.
As of that moment, he had not proved Fermat’s Last Theorem,
and all the mathematical techniques he had developed
to come within 99% of that summit were seemingly as nothing,
such is human psychology.
Luckily, a year later, he found a way around the problem
and was finally credited — along with Richard Taylor — 
with proving this centuries-old conjecture.&lt;/p&gt;

&lt;p&gt;The problem in both cases is that the goal is clear and has a name:
Mount Everest; Fermat’s Last Theorem.
You have to actually stand on the summit;
you have to prove the theorem without exceptions or doubts.
This also applies to the verification of an algorithm,
which is also a mathematical entity.
The verification of an algorithm may be deep and difficult, but it is fundamentally a problem in mathematics.&lt;/p&gt;

&lt;h3 id=&quot;program-verification-is-different&quot;&gt;Program verification is different&lt;/h3&gt;

&lt;p&gt;Program verification is different because 
even the simplest computational task has a messy specification
once we consider real-world constraints.
Suppose our task is to sort an array of records.
Few things are simpler than sorting, yet already we have several correctness properties:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;the output should be a permutation of the input&lt;/li&gt;
  &lt;li&gt;the output should be in order&lt;/li&gt;
  &lt;li&gt;optionally, the sort should be &lt;a href=&quot;https://en.wikipedia.org/wiki/Category:Stable_sorts&quot;&gt;stable&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are just the abstract mathematical requirements for sorting, but in any real world situation
there will also be performance requirements about the space and time used.
These might be expressed asymptotically, as $O(n\ln n)$, but there could also be real-time constraints.&lt;/p&gt;

&lt;p&gt;Now imagine verifying some sorting code. 
The three abstract properties are certainly within the scope of verification,
and if you prove them one at a time, your knowledge is indeed growing as you finish each claim.
Techniques have long existed even for &lt;a href=&quot;https://doi.org/10.1145/321978.321987&quot;&gt;proving resource bounds&lt;/a&gt; 
for your code.
Real-time constraints are another matter.&lt;/p&gt;

&lt;h3 id=&quot;a-few-real-world-case-studies&quot;&gt;A few real-world case studies&lt;/h3&gt;

&lt;p&gt;Most verification tasks are open-ended because software systems are vastly more complicated than sorting, 
and people are always coming up with new new features and new properties to prove of those features.
And that is before we even consider any real-world aspects to the specification.
Here are a few examples:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;the &lt;a href=&quot;https://doi.org/10.1007/978-1-4613-2007-4_4&quot;&gt;Gordon computer&lt;/a&gt; and the &lt;a href=&quot;https://en.wikipedia.org/wiki/VIPER_microprocessor&quot;&gt;VIPER microprocessor&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;various cryptographic protocols, such as &lt;a href=&quot;https://doi.org/10.1145/322510.322530&quot;&gt;TLS&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;the seL4 operating system kernel&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these verification projects consisted of milestones that could be proved one at a time,
our knowledge growing at each step.
None can be called 100% complete.
In the case of VIPER, Avra Cohn felt the need to &lt;a href=&quot;https://rdcu.be/eEkVV&quot;&gt;point out the limitations&lt;/a&gt; 
of her proof, which she felt was being oversold. The design had not been verified down to its lowest level
and the initialisation phase not at all.
In the case of cryptographic protocols, essentially all verification work regards 
the actual cryptographic primitives as abstract and perfect;
real-world TLS has &lt;a href=&quot;https://www.cloudflare.com/en-gb/learning/ssl/why-use-tls-1.3/&quot;&gt;numerous vulnerabilities&lt;/a&gt;.
As for seL4, the &lt;a href=&quot;https://sel4.systems/Verification/&quot;&gt;project page&lt;/a&gt; helpfully lists the underlying assumptions:
“assembly code, boot code, machine interface, hardware, and DMA”.&lt;/p&gt;

&lt;p&gt;Things like assembly code and boot code are in principle verifiable; the only question is the cost.
But in none of these examples is there a summit that could be attained, even with unlimited effort.
For VIPER, we could verify the design right down to the bottom,
but the hardware model assumes digital behaviour for what is actually silicon,
saying nothing about problems that could arise due to gate delays, overheating
or other low-level design errors.
For the same reason, the hardware component of seL4 can never be verified 100%.
Any formal model of hardware could be refined 
to a more accurate and detailed model until you get right down to particle physics,
which itself is only a model of reality.
For cryptographic protocols, we simply do not know how to show that specific encryption methods
are unbreakable.&lt;/p&gt;

&lt;h3 id=&quot;lets-start-climbing-everest&quot;&gt;Let’s start climbing Everest&lt;/h3&gt;

&lt;p&gt;With real-world program verification, we need to be clear about what to prove and what to assume.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;We can prove that our sorting code delivers a sorted permutation of its input
and rely on testing to validate its real-time performance.&lt;/li&gt;
  &lt;li&gt;With cryptographic protocols, the main high-level concern is intricate replay attacks, which today’s abstract models handle well; implementers still must be careful to choose cryptographic primitives known to be secure.&lt;/li&gt;
  &lt;li&gt;A component like seL4 will be &lt;a href=&quot;https://docs.sel4.systems/projects/sel4test/&quot;&gt;tested anyway&lt;/a&gt; as it is integrated into a larger system. Bugs are not found in the verified sections.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope I don’t need to point out that testing alone is inadequate.
It’s not that long ago that computer crashes were an almost daily occurrence.
Things are better now because of &lt;a href=&quot;https://doi.org/10.1145/1218063.1217943&quot;&gt;automated verification tools&lt;/a&gt;.
Even the mighty Microsoft could not achieve stability through testing alone.&lt;/p&gt;

&lt;p&gt;But testing will always have a role to play.
The real world will have to be approximated by some sort of mathematical model.
In the case of verified code, the purpose of testing is to test the model itself.
Increasingly we shall be running verified code on verified hardware designs
while only having to worry about cosmic rays, &lt;a href=&quot;https://meltdownattack.com&quot;&gt;low-level attacks&lt;/a&gt;
and other phenomena that we cannot model or predict.
We won’t be at the summit of Mount Everest, but we’ll still be pretty damn high.&lt;/p&gt;

</description>
				<pubDate>Fri, 05 Sep 2025 00:00:00 +0000</pubDate>
				<link>https://lawrencecpaulson.github.io//2025/09/05/All_or_nothing.html</link>
				<guid isPermaLink="true">https://lawrencecpaulson.github.io//2025/09/05/All_or_nothing.html</guid>
			</item>
		
			<item>
				<title>Definite integrals, II: improper integrals</title>
				<description>&lt;p&gt;&lt;a href=&quot;/2025/08/14/Integrals_I.html&quot;&gt;Last time&lt;/a&gt;, 
we worked out a couple of definite integrals involving discontinuities at the endpoints.
They were easy because the antiderivatives were continuous.
Let’s make things harder by looking at (apparent) discontinuities
and infinite endpoints, both of which require limit reasoning.
We begin by taking a look at the mysteries of the &lt;em&gt;extended real numbers&lt;/em&gt;
and &lt;em&gt;Lebesgue integration&lt;/em&gt;.&lt;/p&gt;

&lt;h3 id=&quot;lebesgue-integration-the-extended-real-numbers&quot;&gt;Lebesgue integration; the extended real numbers&lt;/h3&gt;

&lt;p&gt;The Isabelle/HOL analysis library provides two forms of integration:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;em&gt;Henstock–Kurzweil&lt;/em&gt; or &lt;em&gt;gauge&lt;/em&gt; integral&lt;/li&gt;
  &lt;li&gt;The Lebesgue integral&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Although technically messy, the gauge integral can handle a strict superset of the Lebesgue integrable functions.
However, Lebesgue integration, with its associated measure theory and probability theory,
is the elegant foundation upon which much of analysis has been built.
For Isabelle/HOL users, the overlap may be confusing, and
I think it’s ugly to use both kinds of integral in a single proof.
It’s best not to worry about such trivia.
For difficult improper integrals, Lebesgue is the way to go:
everything you are likely to need is already in the library.&lt;/p&gt;

&lt;p&gt;Many of the key lemmas refer to the &lt;em&gt;extended real numbers&lt;/em&gt;.
These are the real numbers extended with $\infty$ and $-\infty$:
symbols giving us a convenient way to express, for example, 
an integral over an unbounded interval.
The extended reals have type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ereal&lt;/code&gt;, which is also the name of the function
that embeds real numbers into the extended reals.&lt;/p&gt;

&lt;p&gt;It’s important to stress the extended reals do not give any meaningful treatment of &lt;a href=&quot;/2023/02/01/On-the-infinite.html&quot;&gt;infinity&lt;/a&gt;,
such as we get with the &lt;a href=&quot;/2022/08/10/Nonstandard_Analysis.html&quot;&gt;non-standard reals&lt;/a&gt;.
The latter is a field and algebraic facts like $x+y - x = y$ 
hold even for infinite and infinitesimal quantities.
With the extended reals,  $\infty+1 - \infty = \infty - \infty = 0$.
All we get (and want) from the extended reals are two tokens $\infty$ and $-\infty$
satisfying the obvious ordering relations. Then we can express various kinds of
infinite intervals just by giving the lower and upper bounds, 
such as $(-\infty,0]$ or $(1,\infty)$ or $(-\infty,\infty)$.&lt;/p&gt;

&lt;h3 id=&quot;redoing-the-baby-example&quot;&gt;Redoing the baby example&lt;/h3&gt;

&lt;p&gt;We actually saw this example in the &lt;a href=&quot;/2025/08/14/Integrals_I.html&quot;&gt;previous post&lt;/a&gt;:&lt;/p&gt;

\[\begin{equation*} \int_{-1}^1 \frac{1}{\sqrt{1-x^2}}\, dx = \pi \end{equation*}.\]

&lt;p&gt;The first time I did this, I obtained the antiderivative
through WolframAlpha as&lt;/p&gt;

\[\begin{equation*}\displaystyle \tan^{-1} \Bigl({\frac{x}{\sqrt{1-x^2}}}\Bigr)  \end{equation*}.\]

&lt;p&gt;This is the same as $\sin^{-1}(x)$ except for the division by zero at the endpoints.
Moreover, it converges continuously to $\pi/2$ as $x$ tends to $1$ and to $-\pi/2$ as $x$ tends to $-1$:
in other words, the singularities are removable.&lt;/p&gt;

&lt;p&gt;Because the solution using $\sin^{-1}$ is so simple, 
my first plan was to abandon this example, 
but in every simple alternative I looked at, the removable singularity
had already been removed by others: 
for example, $\sin x/x$ is called the &lt;a href=&quot;https://en.wikipedia.org/wiki/Sinc_function&quot;&gt;sinc function&lt;/a&gt;.
And yet, in harder problems, you may have to tackle removable singularities yourself.&lt;/p&gt;

&lt;p&gt;So here is how we deal with this one.
To begin, we need a lemma to replace $x^2&amp;gt;1$ by the disjunction $x&amp;lt;{-1}$ or $x&amp;gt;1$.
(The library already includes the analogous lemma for $x^2=1$.)&lt;/p&gt;

&lt;pre class=&quot;source&quot;&gt;
&lt;span class=&quot;keyword1 command&quot;&gt;lemma&lt;/span&gt; power2_gt_1_iff&lt;span class=&quot;main&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;free&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;&lt;span class=&quot;hidden&quot;&gt;⇧&lt;/span&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;⟷&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;tfree&quot;&gt;&apos;a&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;tclass&quot;&gt;linordered_idom&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∨&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;using&lt;/span&gt; power2_ge_1_iff &lt;span class=&quot;main&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;quoted free&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;]&lt;/span&gt; power2_eq_1_iff &lt;span class=&quot;main&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;quoted free&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;auto&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;Now we set up the proof, with two separate theorem statements.
(With the gauge integral, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;has_integral&lt;/code&gt; relation 
expresses both that the integral is defined and its value.)&lt;/p&gt;

&lt;pre class=&quot;source&quot;&gt;
&lt;span class=&quot;keyword1 command&quot;&gt;lemma&lt;/span&gt; &lt;span class=&quot;quoted quoted&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;set_integrable&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;lborel&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;&amp;lt;..&amp;lt;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;sqrt&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;&lt;span class=&quot;hidden&quot;&gt;⇧&lt;/span&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
      &lt;/span&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword1&quot;&gt;LBINT&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;bound&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;sqrt&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;&lt;span class=&quot;hidden&quot;&gt;⇧&lt;/span&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;pi&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;proof&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;We make three lemmas available to the simplifier (including the one proved above),
and define &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f&lt;/code&gt; to abbreviate the antiderivative.&lt;/p&gt;

&lt;pre class=&quot;source&quot;&gt;
  &lt;span class=&quot;keyword1 command&quot;&gt;note&lt;/span&gt; one_ereal_def &lt;span class=&quot;main&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;simp&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;]&lt;/span&gt; power2_eq_1_iff &lt;span class=&quot;main&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;simp&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;]&lt;/span&gt; power2_gt_1_iff &lt;span class=&quot;main&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;simp&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;]&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword3 command&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;skolem skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;keyword2 keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;quoted quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;≡&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;const&quot;&gt;arctan&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;sqrt&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;&lt;span class=&quot;hidden&quot;&gt;⇧&lt;/span&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;Next, we formally verify the antiderivative by taking its derivative again.
Recall that this is an appeal to the &lt;em&gt;fundamental theorem of calculus&lt;/em&gt; (FTC).
We use a variation on the differentiation technique 
described &lt;a href=&quot;/2025/08/14/Integrals_I.html&quot;&gt;last time&lt;/a&gt;,
showing that the extracted derivative equals $\frac{1}{\sqrt{1-x^2}}$.&lt;/p&gt;

&lt;pre class=&quot;source&quot;&gt;
  &lt;span class=&quot;keyword1 command&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;keyword1&quot;&gt;has_real_derivative&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;sqrt&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;-x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;&lt;span class=&quot;hidden&quot;&gt;⇧&lt;/span&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword1&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword2 keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;keyword2 keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;unfolding&lt;/span&gt; f_def&lt;span&gt; 
    &lt;/span&gt;&lt;span class=&quot;keyword1 command improper command&quot;&gt;apply&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;rule&lt;/span&gt; refl &lt;span class=&quot;dynamic dynamic&quot;&gt;derivative_eq_intros&lt;/span&gt; &lt;span class=&quot;main keyword3&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;use&lt;/span&gt; that &lt;span class=&quot;keyword2 keyword quasi_keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;force&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main keyword3&quot;&gt;+&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command improper command&quot;&gt;apply&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;simp&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; power2_eq_square &lt;span class=&quot;dynamic dynamic&quot;&gt;divide_simps&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command improper command&quot;&gt;done&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;Setting aside this result using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;moreover&lt;/code&gt;, we prove continuity of the integrand
on the &lt;strong&gt;open&lt;/strong&gt; interval $(-1,1)$. (We shall deal with the endpoints later.)
As mentioned last time, proving continuity is trivial 
with the help of the theorem list &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;continuous_intros&lt;/code&gt;.
The final call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto&lt;/code&gt; is to prove that the divisor is nonzero.&lt;/p&gt;

&lt;pre class=&quot;source&quot;&gt;
  &lt;span class=&quot;keyword1 command&quot;&gt;moreover&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;quoted quoted&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;isCont&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;sqrt&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;&lt;span class=&quot;hidden&quot;&gt;⇧&lt;/span&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword2 keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;keyword2 keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;using&lt;/span&gt; that &lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;intro&lt;/span&gt; &lt;span class=&quot;dynamic dynamic&quot;&gt;continuous_intros&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;auto&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;The next step is trivial but vital.
The version of the FTC I’m using requires the integrand to be nonnegative.
In a moment, we’ll look at another example where it isn’t.&lt;/p&gt;

&lt;pre class=&quot;source&quot;&gt;
  &lt;span class=&quot;keyword1 command&quot;&gt;moreover&lt;/span&gt;
  &lt;span class=&quot;keyword1 command&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;0&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;≤&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;sqrt&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;-x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;&lt;span class=&quot;hidden&quot;&gt;⇧&lt;/span&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword2 keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;keyword2 keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;using&lt;/span&gt; that &lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;simp&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; square_le_1&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;Our version of the FTC deals with discontinuity at the endpoints
using limits. The theorem refers to the extended reals throughout,
which I’ve managed to conceal so far: Isabelle can usually mediate
between the reals and the extended reals.
They become explicit here. The actual limit reasoning is done by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;real_asymp&lt;/code&gt;
proof method, demonstrated in a &lt;a href=&quot;/2024/08/08/Ln_lower_bound.html&quot;&gt;previous post&lt;/a&gt;.&lt;/p&gt;

&lt;pre class=&quot;source&quot;&gt;
  &lt;span class=&quot;keyword1 command&quot;&gt;moreover&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;⤏&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;pi&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;numeral&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;at_right&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;  &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;⤏&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;const&quot;&gt;pi&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;numeral&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;at_left&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;unfolding&lt;/span&gt; f_def &lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;real_asymp&lt;/span&gt;&lt;span class=&quot;main keyword3&quot;&gt;+&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;keyword1 command&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∘&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;const&quot;&gt;real_of_ereal&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;⤏&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;pi&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;numeral&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;at_right&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
            &lt;/span&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∘&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;const&quot;&gt;real_of_ereal&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;⤏&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;pi&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;numeral&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;at_left&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;simp_all&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; ereal_tendsto_simps1&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;Now we can conclude the proof. The keyword &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ultimately&lt;/code&gt;
brings in all of the facts that had been set aside using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;moreover&lt;/code&gt;,
and we insert a specific instance of the FTC, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;interval_integral_FTC_nonneg&lt;/code&gt;, 
instantiated with the relevant parameters.
This works because in the previous steps we proved all of its pre-conditions.&lt;/p&gt;

&lt;pre class=&quot;source&quot;&gt;
  &lt;span class=&quot;keyword1 command&quot;&gt;ultimately&lt;/span&gt; &lt;span class=&quot;keyword3 command&quot;&gt;show&lt;/span&gt;&lt;span&gt; 
    &lt;/span&gt;&lt;span class=&quot;quoted quoted&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;set_integrable&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;lborel&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;&amp;lt;..&amp;lt;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;sqrt&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;&lt;span class=&quot;hidden&quot;&gt;⇧&lt;/span&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword1&quot;&gt;LBINT&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;bound&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;sqrt&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;&lt;span class=&quot;hidden&quot;&gt;⇧&lt;/span&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;pi&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;using&lt;/span&gt; interval_integral_FTC_nonneg &lt;span class=&quot;main&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;quoted quoted quoted&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;quoted main&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;quoted skolem quoted skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;quoted quoted quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;bound bound&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;.&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;sqrt&lt;/span&gt; &lt;span class=&quot;main main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;bound bound&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;&lt;span class=&quot;hidden&quot;&gt;⇧&lt;/span&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;quoted quoted quoted&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;pi&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;numeral numeral&quot;&gt;2&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;quoted quoted quoted&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;pi&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;numeral numeral&quot;&gt;2&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;]&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;auto&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;qed&lt;/span&gt;
&lt;/pre&gt;

&lt;h3 id=&quot;integration-over-the-entire-real-line&quot;&gt;Integration over the entire real line&lt;/h3&gt;

&lt;p&gt;Our next example is properly improper, because the endpoints are infinite.&lt;/p&gt;

\[\begin{equation*} \int_{-\infty}^\infty \frac{1}{t^2+1}\, dt = \pi \end{equation*}\]

&lt;p&gt;Here is its graph. Once again we have a non-negative integrand.&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;
  &lt;img src=&quot;/images/integral-3.png&quot; alt=&quot;graph of 3rd integral, 1 / (t^2+1)&quot; width=&quot;300&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;Maple tells us that the antiderivative is $\tan^{-1}t$.
(I have also used Maple for all these graphs.)&lt;/p&gt;

&lt;p&gt;Once again, Lebesgue integration is the way to go,
since the necessary machinery has not been set up for gauge integrals.
The formal proof has the same structure as in the previous example.
We verify the antiderivative, show continuity of the integrand
and also show the integrand to be nonnegative.
Finally, we apply the FTC to obtain the two conclusions.&lt;/p&gt;

&lt;pre class=&quot;source&quot;&gt;
&lt;span class=&quot;keyword1 command&quot;&gt;lemma&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword2 keyword&quot;&gt;defines&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;free&quot;&gt;f&apos;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;≡&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;/&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;&lt;span class=&quot;hidden&quot;&gt;⇧&lt;/span&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword2 keyword&quot;&gt;shows&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;quoted quoted&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;set_integrable&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;lborel&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;einterval&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;∞&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∞&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;f&apos;&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword1&quot;&gt;LBINT&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;∞&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;∞&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;f&apos;&lt;/span&gt; &lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;pi&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;proof&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;quoted quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;arctan&lt;/span&gt; &lt;span class=&quot;keyword1&quot;&gt;has_real_derivative&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;f&apos;&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword1&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;keyword2 keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;t&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;unfolding&lt;/span&gt; f&apos;_def&lt;span&gt; 
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;rule&lt;/span&gt; &lt;span class=&quot;dynamic dynamic&quot;&gt;derivative_eq_intros&lt;/span&gt; &lt;span class=&quot;main keyword3&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;force&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;simp&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dynamic dynamic&quot;&gt;divide_simps&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main keyword3&quot;&gt;+&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;moreover&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;quoted quoted&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;isCont&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;f&apos;&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;keyword2 keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;unfolding&lt;/span&gt; f&apos;_def&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;intro&lt;/span&gt; &lt;span class=&quot;dynamic dynamic&quot;&gt;continuous_intros&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;simp&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; add_nonneg_eq_0_iff&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt; 
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;moreover&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;quoted quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;arctan&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∘&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;real_of_ereal&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;⤏&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;pi&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;numeral&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;at_right&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;∞&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
       &lt;/span&gt;&lt;span class=&quot;quoted quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;arctan&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∘&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;real_of_ereal&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;⤏&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;pi&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;numeral&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;at_left&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∞&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;simp&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; ereal_tendsto_simps1&lt;span class=&quot;main keyword3&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;real_asymp&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main keyword3&quot;&gt;+&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;ultimately&lt;/span&gt; &lt;span class=&quot;keyword3 command&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;quoted quoted&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;set_integrable&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;lborel&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;einterval&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;∞&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∞&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;f&apos;&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;quoted quoted&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;interval_lebesgue_integral&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;lborel&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;∞&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∞&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;f&apos;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;pi&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;using&lt;/span&gt; interval_integral_FTC_nonneg &lt;span class=&quot;main&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;quoted quoted quoted&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;∞&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;quoted main&quot;&gt;∞&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;arctan&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;]&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;simp&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; f&apos;_def&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;qed&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;There are a couple of differences from the previous proof.
We do not need an abbreviation for the antiderivative because it is simply
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arctan&lt;/code&gt;.
But this proof features a local definition of the integrand
as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f&apos;&lt;/code&gt;, and we could have done something similar last time.&lt;/p&gt;

&lt;h3 id=&quot;integration-of-a-sign-changing-function&quot;&gt;Integration of a sign-changing function&lt;/h3&gt;

&lt;p&gt;If you are unsure why a sign-changing function 
needs a different version of the FTC, consider that $\cos$
is both differentiable and continuous. 
Without the non-negative condition, the FTC would tell us that
$\cos$ could be integrated over the whole real line, which is ridiculous.&lt;/p&gt;

&lt;p&gt;And so our final example is to integrate a &lt;a href=&quot;https://www.statisticshowto.com/calculus-definitions/damped-sine-wave/&quot;&gt;damped sinusoid&lt;/a&gt; 
over the non-negative real numbers.&lt;/p&gt;

\[\begin{equation*} \int_0^\infty e^{-t}\cos t\, dt = \frac{1}{2} \end{equation*}\]

&lt;p&gt;Here is the graph. It’s hard to see, but this function crosses the $x$-axis infinitely often.&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;
  &lt;img src=&quot;/images/integral-4.png&quot; alt=&quot;graph of 4th integral, exp(-t)cos(t)&quot; width=&quot;300&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;Because its sign changes, the integration proof involves two steps:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Show that the integral exists. Since $\lvert e^{-t}\cos t\rvert \le e^{-t}$, 
we need to show that the latter function is integrable.
It is non-negative, so we apply the previous version of the FTC.&lt;/li&gt;
  &lt;li&gt;We apply a signed version of the FTC to verify what the value of the integral
actually is.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s do the formal proof.
We start with the theorem statement, including as before
a local definition of the integrand.&lt;/p&gt;

&lt;pre class=&quot;source&quot;&gt;
&lt;span class=&quot;keyword1 command&quot;&gt;lemma&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword2 keyword&quot;&gt;defines&lt;/span&gt; &lt;span class=&quot;quoted quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;free&quot;&gt;f&apos;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;≡&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;const&quot;&gt;exp&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt; * &lt;/span&gt;&lt;span class=&quot;const&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword2 keyword&quot;&gt;shows&lt;/span&gt;  &lt;span class=&quot;quoted quoted&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;set_integrable&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;lborel&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;einterval&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∞&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;f&apos;&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
         &lt;/span&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword1&quot;&gt;LBINT&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;∞&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;f&apos;&lt;/span&gt; &lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;numeral&quot;&gt;2&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;keyword1 command&quot;&gt;proof&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;
&lt;/pre&gt;

&lt;h4 id=&quot;the-first-result&quot;&gt;The first result&lt;/h4&gt;

&lt;p&gt;Concerning step 1 above, we show that $e^{-t}$ is integrable.
The proof relies on the FTC for non-negative functions, just as we’ve already.
Our task this time is slightly simpler because we don’t care what the integral actually is.
(It’s 1.)
We can therefore ignore the second conclusion of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;interval_integral_FTC_nonneg&lt;/code&gt;
and write the proof as follows:&lt;/p&gt;

&lt;pre class=&quot;source&quot;&gt;
  &lt;span class=&quot;keyword1 command&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;quoted quoted&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;set_integrable&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;lborel&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;einterval&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∞&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;exp&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;proof&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;rule&lt;/span&gt; interval_integral_FTC_nonneg&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword3 command&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;quoted quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;exp&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword1&quot;&gt;has_real_derivative&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;exp&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword1&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;keyword2 keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;t&lt;/span&gt;&lt;span&gt;
      &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;rule&lt;/span&gt; &lt;span class=&quot;dynamic dynamic&quot;&gt;derivative_eq_intros&lt;/span&gt; &lt;span class=&quot;main keyword3&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;force&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;simp&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dynamic dynamic&quot;&gt;field_simps&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main keyword3&quot;&gt;+&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;quoted quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;exp&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∘&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;real_of_ereal&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;⤏&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;at_right&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;ereal&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
      &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;simp&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; ereal_tendsto_simps1&lt;span class=&quot;main keyword3&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;real_asymp&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;keyword3 command&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;quoted quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;exp&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∘&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;real_of_ereal&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;⤏&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;at_right&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
      &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;simp&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; zero_ereal_def&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword3 command&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;const&quot;&gt;exp&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∘&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;real_of_ereal&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;⤏&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;at_left&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∞&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
      &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;simp&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; ereal_tendsto_simps1&lt;span class=&quot;main keyword3&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;real_asymp&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;qed&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;auto&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;Setting this fact aside, we prove a necessary technical condition: 
that the integrand is a &lt;em&gt;measurable function&lt;/em&gt;
on the closed interval $[0,\infty]$.&lt;/p&gt;

&lt;pre class=&quot;source&quot;&gt;
  &lt;span class=&quot;keyword1 command&quot;&gt;moreover&lt;/span&gt; &lt;span class=&quot;keyword1 command&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;quoted quoted&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;set_borel_measurable&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;lborel&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;einterval&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∞&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;f&apos;&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;using&lt;/span&gt; borel_measurable_continuous_on_indicator&lt;span&gt; 
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;simp&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; f&apos;_def set_borel_measurable_def&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;We store this fact as well, and then prove that the integrand is
absolutely bounded by $e^{-t}$.&lt;/p&gt;

&lt;pre class=&quot;source&quot;&gt;
  &lt;span class=&quot;keyword1 command&quot;&gt;moreover&lt;/span&gt; &lt;span class=&quot;keyword1 command&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;⋀&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;¦&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;free&quot;&gt;f&apos;&lt;/span&gt; &lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;¦&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;≤&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;exp&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;simp&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; f&apos;_def abs_mult&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;Combining the facts proved above, we find that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f&apos;&lt;/code&gt; is indeed integrable over $[0,\infty]$.
This is the first conclusion of the theorem, 
but we also label it because it’s needed to prove the second conclusion.&lt;/p&gt;

&lt;pre class=&quot;source&quot;&gt;
  &lt;span class=&quot;keyword1 command&quot;&gt;ultimately&lt;/span&gt; &lt;span class=&quot;keyword3 command&quot;&gt;show&lt;/span&gt; *&lt;span class=&quot;main&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;quoted quoted&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;set_integrable&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;lborel&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;einterval&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∞&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;f&apos;&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;metis&lt;/span&gt; &lt;span class=&quot;main main&quot;&gt;(&lt;/span&gt;mono_tags&lt;span class=&quot;main main&quot;&gt;,&lt;/span&gt; lifting&lt;span class=&quot;main main&quot;&gt;)&lt;/span&gt; abs_exp_cancel always_eventually&lt;span&gt;
        &lt;/span&gt;real_norm_def set_integrable_bound set_integrable_bound&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;

&lt;h4 id=&quot;the-second-result&quot;&gt;The second result&lt;/h4&gt;

&lt;p&gt;Now we turn to step 2. We insert a local definition of the antiderivative,
which happens to be \(e^{-t}\frac{\sin t - \cos t}{2}\).
To prove the second conclusion, we express the integral as the difference
between two values at the endpoints and apply the more general version of the FTC.&lt;/p&gt;

&lt;pre class=&quot;source&quot;&gt;
  &lt;span class=&quot;keyword3 command&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;skolem skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;keyword2 keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;quoted quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;≡&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;tconst&quot;&gt;real&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;exp&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt; / &lt;/span&gt;&lt;span class=&quot;numeral&quot;&gt;2&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword1&quot;&gt;LBINT&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;∞&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;f&apos;&lt;/span&gt; &lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;numeral&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;proof&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;intro&lt;/span&gt; interval_integral_FTC_integrable&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;The next steps should be familiar by now. For an arbitrary real number &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;t&lt;/code&gt;,
we verify the antiderivative by differentiation and prove the integrand to be continuous.&lt;/p&gt;

&lt;pre class=&quot;source&quot;&gt;
    &lt;span class=&quot;keyword3 command&quot;&gt;fix&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;t&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword3 command&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;keyword1&quot;&gt;has_vector_derivative&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;f&apos;&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword1&quot;&gt;at&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
      &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;unfolding&lt;/span&gt; f_def f&apos;_def has_real_derivative_iff_has_vector_derivative &lt;span class=&quot;main&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;symmetric&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;]&lt;/span&gt;&lt;span&gt;
      &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;rule&lt;/span&gt; &lt;span class=&quot;dynamic dynamic&quot;&gt;derivative_eq_intros&lt;/span&gt; &lt;span class=&quot;main keyword3&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;force&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;simp&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dynamic dynamic&quot;&gt;field_simps&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main keyword3&quot;&gt;+&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword3 command&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;quoted quoted&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;isCont&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;f&apos;&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;t&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
      &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;unfolding&lt;/span&gt; f&apos;_def &lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;intro&lt;/span&gt; &lt;span class=&quot;dynamic dynamic&quot;&gt;continuous_intros&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;The FTC requires us to verify the values attained by the antiderivative at the endpoints.
Which we do using the techniques we’ve seen before, 
in particular, a couple of awkward tricks needed because everything has to be proved in terms of the extended real numbers.&lt;/p&gt;

&lt;pre class=&quot;source&quot;&gt;
  &lt;span class=&quot;keyword1 command&quot;&gt;next&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∘&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;const&quot;&gt;real_of_ereal&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;⤏&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;numeral&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;at_right&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;ereal&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
      &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;simp&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; ereal_tendsto_simps1 f_def&lt;span class=&quot;main keyword3&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;real_asymp&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;keyword3 command&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∘&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;const&quot;&gt;real_of_ereal&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;⤏&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;numeral&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;at_right&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
      &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;simp&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; zero_ereal_def&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword3 command&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∘&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;const&quot;&gt;real_of_ereal&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;⤏&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;at_left&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;∞&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
      &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;simp&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; ereal_tendsto_simps1 f_def&lt;span class=&quot;main keyword3&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;real_asymp&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;Now &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto&lt;/code&gt; (given the first result, namely &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*&lt;/code&gt;) wraps up the proof.&lt;/p&gt;

&lt;pre class=&quot;source&quot;&gt;
  &lt;span class=&quot;keyword1 command&quot;&gt;qed&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;use&lt;/span&gt; * &lt;span class=&quot;keyword2 keyword quasi_keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;keyword3 command&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword1&quot;&gt;LBINT&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;∞&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;free&quot;&gt;f&apos;&lt;/span&gt; &lt;span class=&quot;bound&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;numeral&quot;&gt;2&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;simp&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;qed&lt;/span&gt;
&lt;/pre&gt;

&lt;h3 id=&quot;a-few-concluding-remarks&quot;&gt;A few concluding remarks&lt;/h3&gt;

&lt;p&gt;As we have seen, an Isabelle theorem declaration can have multiple conclusions.
In the case of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;interval_integral_FTC_nonneg&lt;/code&gt;, it makes sense because
both conclusions depend on the same premises and much of the same reasoning.
In the last example, I did this simply for the sake of uniformity.
In the case of gauge integrals, Isabelle provides &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;has_integral&lt;/code&gt;
to express that the integral exists and has the given value.
Somewhat similarly, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;has_bochner_integral&lt;/code&gt; refers to Lebesgue integrals,
but it is a bit clunky for integrating over the real line.&lt;/p&gt;

&lt;p&gt;The Isabelle theory file formalising the examples in this and the previous post 
are &lt;a href=&quot;/Isabelle-Examples/Improper_Integral.thy&quot;&gt;online&lt;/a&gt;.&lt;/p&gt;

</description>
				<pubDate>Thu, 21 Aug 2025 00:00:00 +0000</pubDate>
				<link>https://lawrencecpaulson.github.io//2025/08/21/Integrals_II.html</link>
				<guid isPermaLink="true">https://lawrencecpaulson.github.io//2025/08/21/Integrals_II.html</guid>
			</item>
		
			<item>
				<title>Definite integrals, I: easy cases over finite intervals</title>
				<description>&lt;p&gt;On occasion, your Isabelle proof may require you to work with a &lt;em&gt;definite integral&lt;/em&gt;.
(That is, the area under a curve between two points on the &lt;em&gt;x&lt;/em&gt;-axis.)
In the simplest case, all we have to do is
integrate the given function to obtain its &lt;em&gt;antiderivative&lt;/em&gt;, which we then evaluate at the endpoints, returning the difference.
But things are not always simple. There could be discontinuities in the &lt;em&gt;integrand&lt;/em&gt; (the function being integrated)
or in its antiderivative. Either or both of the endpoints could be infinite.
And while we say “area under a curve”, our notion of area is in fact signed,
going negative when the curve crosses the &lt;em&gt;x&lt;/em&gt;-axis.
Finally, Isabelle has no actual capability to take integrals.
Let’s work through a few examples in which we symbolically evaluate a definite integral, 
proving that the result is correct.&lt;/p&gt;

&lt;h3 id=&quot;a-baby-example&quot;&gt;A baby example&lt;/h3&gt;

&lt;p&gt;Let’s begin with the following integral:&lt;/p&gt;

\[\begin{equation*} \int_{-1}^1 \frac{1}{\sqrt{1-x^2}}\, dx = \pi \end{equation*}\]

&lt;p&gt;Here is a graph of the integrand. 
It goes to infinity at both endpoints. Still, the integral is defined.&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;
 &lt;img src=&quot;/images/integral-1.png&quot; alt=&quot;graph of 1st integral, 1 / sqrt(1-x^2)&quot; width=&quot;300&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;The antiderivative is $\sin^{-1}$, the inverse sine function, which is continuous.
The integral is $\sin^{-1}(1) - \sin^{-1}(-1) = \frac{\pi}{2} - (-\frac{\pi}{2}) = \pi$.&lt;/p&gt;

&lt;p&gt;To do this in Isabelle, our first task is to carry out the integration.
Isabelle has no such capability, but that doesn’t matter: 
Isabelle can differentiate, so we simply use some external tool to integrate,
confirming its answer by formally proving that its derivative matches the original integrand. 
This is an appeal to the &lt;em&gt;Fundamental Theorem of Calculus&lt;/em&gt; (FTC),
which says that integration and differentiation are inverse operations of each other.
The Isabelle libraries provide numerous variants of this fact.&lt;/p&gt;

&lt;p&gt;As for the external tool:
&lt;a href=&quot;https://www.wolframalpha.com&quot;&gt;WolframAlpha&lt;/a&gt;, which is free, can often do the job,
but here I needed &lt;a href=&quot;https://www.maplesoft.com/products/maple/index.aspx&quot;&gt;Maple&lt;/a&gt; 
to find out that the antiderivative was simply the inverse sine.&lt;/p&gt;

&lt;p&gt;The Isabelle proof is so simple, there is almost nothing to say.
The key point is the form of the FTC chosen: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fundamental_theorem_of_calculus_interior&lt;/code&gt;,
which allows the integrand to diverge at the endpoints provided the antiderivative is continuous over the full closed interval.&lt;/p&gt;

&lt;pre class=&quot;source&quot;&gt;
&lt;span class=&quot;keyword1 command&quot;&gt;lemma&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;/&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;sqrt&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;&lt;span class=&quot;hidden&quot;&gt;⇧&lt;/span&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword1&quot;&gt;has_integral&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;pi&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;proof&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;quoted quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;arcsin&lt;/span&gt; &lt;span class=&quot;keyword1&quot;&gt;has_real_derivative&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;sqrt&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;&lt;span class=&quot;hidden&quot;&gt;⇧&lt;/span&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword1&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword2 keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;-&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;keyword2 keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt;&lt;span&gt; 
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;rule&lt;/span&gt; refl &lt;span class=&quot;dynamic dynamic&quot;&gt;derivative_eq_intros&lt;/span&gt; &lt;span class=&quot;main keyword3&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;use&lt;/span&gt; that &lt;span class=&quot;keyword2 keyword quasi_keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;‹&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;simp&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;dynamic dynamic&quot;&gt;divide_simps&lt;/span&gt;&lt;span&gt;›&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main keyword3&quot;&gt;+&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;keyword3 command&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;var quoted var&quot;&gt;?thesis&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;using&lt;/span&gt; fundamental_theorem_of_calculus_interior &lt;span class=&quot;main&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;OF&lt;/span&gt; _ continuous_on_arcsin&apos;&lt;span class=&quot;main&quot;&gt;]&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;simp&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; has_real_derivative_iff_has_vector_derivative&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;qed&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;The proof begins by showing that the derivative of $\sin^{-1}$
is indeed $\frac{1}{\sqrt{1-x^2}}$, 
though &lt;strong&gt;only on the open interval&lt;/strong&gt; $({-1},1)$.
This fact, along with the continuity of $\sin^{-1}$, is supplied to the FTC, which
sets up the calculation of $\sin^{-1}(1) - \sin^{-1}(-1)$.&lt;/p&gt;

&lt;h2 id=&quot;a-just-slightly-harder-example&quot;&gt;A just slightly harder example&lt;/h2&gt;

&lt;p&gt;This next example, $\int_0^1 \frac{1}{\sqrt{x}}\, dx = 2$, presents the same difficulty: divergence at an endpoint.&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;
  &lt;img src=&quot;/images/integral-2.png&quot; alt=&quot;graph of 2nd integral, 1 / sqrt x&quot; width=&quot;300&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;Mathematically, its treatment is identical to the previous example.
The integrand diverges at zero. Its antiderivative is $2\sqrt{x}$,
which fortunately is continuous for all $x\ge0$.&lt;/p&gt;

&lt;p&gt;As for the formal proof,
we use a little Isar to introduce the abbreviation &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f&lt;/code&gt; for the antiderivative, 
which is referred to a number of times.
We prove that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f&lt;/code&gt; is continuous over the closed interval and verify
that it has the correct derivative over the open interval, 
avoiding the discontinuity at zero.&lt;/p&gt;

&lt;pre class=&quot;source&quot;&gt;
&lt;span class=&quot;keyword1 command&quot;&gt;lemma&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;/&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;sqrt&lt;/span&gt; &lt;span class=&quot;bound&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword1&quot;&gt;has_integral&lt;/span&gt; &lt;span class=&quot;numeral&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;proof&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;-&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword3 command&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;skolem skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;keyword2 keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;≡&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;numeral&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;*&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;const&quot;&gt;sqrt&lt;/span&gt; &lt;span class=&quot;bound&quot;&gt;x&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;keyword1&quot;&gt;has_real_derivative&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;sqrt&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;keyword1&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword2 keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;0&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;keyword2 keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;x&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;unfolding&lt;/span&gt; f_def&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;rule&lt;/span&gt; refl &lt;span class=&quot;dynamic dynamic&quot;&gt;derivative_eq_intros&lt;/span&gt; &lt;span class=&quot;main keyword3&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;use&lt;/span&gt; that &lt;span class=&quot;keyword2 keyword quasi_keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;‹&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;simp&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;dynamic dynamic&quot;&gt;divide_simps&lt;/span&gt;&lt;span&gt;›&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main keyword3&quot;&gt;+&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;moreover&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;quoted quoted&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;const&quot;&gt;continuous_on&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;f&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;simp&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; continuous_on_mult continuous_on_real_sqrt f_def&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;ultimately&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;have&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;λ&lt;/span&gt;&lt;span class=&quot;bound&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;/&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;const&quot;&gt;sqrt&lt;/span&gt; &lt;span class=&quot;bound&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;keyword1&quot;&gt;has_integral&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;skolem&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;intro&lt;/span&gt; fundamental_theorem_of_calculus_interior&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;
       &lt;/span&gt;&lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;simp&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; has_real_derivative_iff_has_vector_derivative&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;
  &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;keyword3 command&quot;&gt;show&lt;/span&gt; &lt;span class=&quot;var quoted var&quot;&gt;?thesis&lt;/span&gt;&lt;span&gt; 
    &lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;simp&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; f_def&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span class=&quot;keyword1 command&quot;&gt;qed&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;If the integrand is differentiable over the closed interval, 
then the proof can be done using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fundamental_theorem_of_calculus&lt;/code&gt;,
a version of the FTC that does not require a separate proof of continuity.&lt;/p&gt;

&lt;h3 id=&quot;taking-derivatives-in-isabelle&quot;&gt;Taking derivatives in Isabelle&lt;/h3&gt;

&lt;p&gt;It’s easy to take the derivative of a function or to prove that it is continuous.
Isabelle does not provide dedicated proof methods for such tasks,
relying instead on its own Prolog-like proof engine.
Above we used the following line, although variations are possible:&lt;/p&gt;

&lt;pre class=&quot;source&quot;&gt;
    &lt;span class=&quot;keyword1 command&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;main&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;rule&lt;/span&gt; refl &lt;span class=&quot;dynamic dynamic&quot;&gt;derivative_eq_intros&lt;/span&gt; &lt;span class=&quot;main keyword3&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;use&lt;/span&gt; that &lt;span class=&quot;keyword2 keyword quasi_keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;quoted&quot;&gt;&lt;span&gt;‹&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;simp&lt;/span&gt; &lt;span class=&quot;quasi_keyword&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;main main&quot;&gt;:&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;dynamic dynamic&quot;&gt;divide_simps&lt;/span&gt;&lt;span&gt;›&lt;/span&gt;&lt;span class=&quot;main&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;main keyword3&quot;&gt;+&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;Key is the theorem list &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;derivative_eq_intros&lt;/code&gt;, which as of today has more than 140 entries.
A typical one says in essence that to show that the derivative of $\lambda x. f (x) + g(x)$ is $h$, show the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;that the derivative of $f$ is some $f’$,&lt;/li&gt;
  &lt;li&gt;that the derivative of $g$ is some $g’$,&lt;/li&gt;
  &lt;li&gt;that $(\lambda x. f’ (x) + g’(x)) = h$.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The point is that both $f’$ and $g’$ will be logical variables (in the Prolog sense),
so the repetitive application of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;derivative_eq_intros&lt;/code&gt; can calculate the derivatives of the subterms into them. We alternate with simplifier calls because the result of the raw process produces terms like $0\cdot x^1 + 1\cdot x^0$. But if the simplifier alters the outer form of the equations, say by moving a term across the equals sign, then the process probably won’t work. A little tinkering is sometimes necessary.&lt;/p&gt;

&lt;p&gt;To prove that a function is continuous, use the theorem list &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;continuous_intros&lt;/code&gt;.
The idea is similar to differentiation: in fact a lot simpler, 
because there is nothing to calculate.
Therefore there is no need to call the simplifier.
We shall see several continuity proofs in the forthcoming Part II.&lt;/p&gt;
</description>
				<pubDate>Thu, 14 Aug 2025 00:00:00 +0000</pubDate>
				<link>https://lawrencecpaulson.github.io//2025/08/14/Integrals_I.html</link>
				<guid isPermaLink="true">https://lawrencecpaulson.github.io//2025/08/14/Integrals_I.html</guid>
			</item>
		
	</channel>
</rss>
