Schemes in Lean

We tell the story of how schemes were formalised in three different ways in the Lean theorem prover.


Introduction and overview
1.1. Varieties and schemes in algebraic geometry. Before 1960, algebraic geometry was done via the theory of algebraic varieties, finite-dimensional objects defined over a fixed algebraically closed field, or "universal domain". The standard reference text was Weil's 1946 book "Foundations of algebraic geometry" [Wei46], and in the final chapter "Comments and discussions", Weil remarks that "it would be very convenient to have. . . a principle of reduction modulo p ", a phenomenon which Weil would have known well should exist but which was extremely inconvenient to do in this setting.
Schemes were introduced by Grothendieck in the 1960s (following earlier ideas of Chevalley, and building on ideas of Zariski) as the building blocks for a new algebraic geometry. Grothendieck did not need to work over a fixed base field; his foundations worked with general commutative rings rather than algebraically closed fields, enabling reduction modulo p to become possible. Given a general "geometric object" (for example, a topological space), one can consider the set of continuous real-valued functions on this object, and pointwise addition and multiplication turn this space of functions into a commutative ring. Grothendieck's observation was that one could make a construction in the opposite direction: starting with an arbitrary commutative ring R, he constructed a geometric object Spec (R) called an affine scheme; this was a topological space equipped with a sheaf of functions O X on this space, such that O X (Spec (R)), the "allowable" functions on Spec (R), was R again. Grothendieck defined a general scheme by gluing affine schemes together (following Weil, who in [Wei46] had defined an abstract variety by gluing affine varieties together 1 ). This new viewpoint proved incisive -ten years later the Weil conjectures, questions about the number of points which algebraic varieties have over finite fields, were being proved using machinery such asétale cohomology, which had been developed using schemes.
1.2. Formalising schemes -the history. As mentioned in the abstract, schemes were formalised three times in Lean [dKA + 15]; each formalisation was better-behaved than the one before.
The first formalisation was by the first three authors (KB, CH, KL), and it evolved in late 2017 and early 2018 from the Thursday evening Xena Project meetings at Imperial College London, where undergraduates learn how to formalise mathematics in Lean (KB is the staff member running the meetings; CH and KL were, at the time, first year mathematics undergraduates). It started with KL formalising the theory of localisation of rings as a project, and with KB suggesting that schemes would be a natural way to take the theory further in Lean. It was their first attempt to formalise anything non-trivial in a theorem prover (and its ultimate success inspired KB to see exactly how far Lean could be pushed, eventually resulting in [BCM20]). However some poor (in retrospect) design decisions were made when it came to the theory of localisation, and in this first iteration these decisions resulted in messy infrastructure which would not scale. It quickly became clear that an extensive rewrite was needed. It also became apparent that such a formalisation had never been embarked upon before in any other theorem prover (parts of the theory of affine schemes had been formalised, but nothing approaching the definition of a scheme) -this perhaps says something about the interests of mathematical formalisation community, at least pre-2017. The (abandoned) project is still currently online at [BHL18].
AL and RFM then joined the project, with AL developing a very robust theory of localisation in the form which was needed, and RFM rewriting the definition of a scheme from scratch as part of his 2018-2019 MSc project supervised by KB. RFM ultimately produced a definition which was usable -indeed several other basic results from the Stacks project website [Sta21] and Hartshorne's algebraic geometry textbook [Har77] were also proved in this iteration, mostly by KL. This version is currently online at [FM19].
However, sheaves were defined "by hand" in this iteration; there was one definition for a sheaf of types (or sheaf of sets, depending on your foundations), one for a sheaf of abelian groups and another one for a sheaf of rings. The contribution of SM was to build enough abstract category theory in Lean to enable a third definition using this category-theoretic language. At this point a design change was also made; the definition of the sheaf on Spec (R) was changed from the definition in [Sta21] to the equivalent definition in [Har77]. This was the version which finally made it into Lean's mathematics library, in commit b79fc0379ae786153fc22ce5ee6751505e36a3d9 of mathlib [mat20, src/algebraic geometry/Scheme.lean]. The current mathlib documentation for schemes (perhaps more readable for people who do not want to look directly at the code) is available at the Lean community website.
1.3. Organisation of the paper. Most of the formalisation was plain sailing, but occasionally we ran into unexpected problems. The layout of this paper is as follows. In the next section we go over the details of some of the mathematics involved. In the three sections after that we explain the three approaches to formalising the material, emphasising the parts which did not go smoothly and explaining how this affected future design decisions.

Mathematical details.
Convention: all rings are commutative and have a 1; all ring homomorphisms send 1 to 1. Let X be a topological space. A presheaf of rings F on X is a way to associate a ring F (U ) to each open subset U ⊆ X, and a ring homomorphism ρ UV : F (U ) → F (V ) to each inclusion V ⊆ U of open subsets of X, such that ρ UU is the identity for all opens U , and In other words, F is a contravariant functor from the category of open subsets of X to the category of rings. If f ∈ F (U ) and V ⊆ U , we write f | V as shorthand for ρ UV (f ). The model example to keep in mind is where F (U ) is defined to be the ring of continuous functions U → R, and ρ V U sends a continuous function on U to its restriction to V .
A presheaf of rings F is said to be a sheaf of rings if elements of F (U ) can "be defined locally". More precisely, a presheaf of rings F is a sheaf of rings if for every open set U and every open cover U = i∈I U i of U by open sets U i , the sequence In words, the exactness of ( ‡) is the assertion that if you have a collection of elements f i ∈ F (U i ) which agree on all overlaps U i ∩ U j , then there is a unique f ∈ F (U ) whose restriction to U i is f i for all i. A topological space X equipped with a sheaf of rings O X is called a ringed space.
If (X, O X ) is a ringed space, then to each point u ∈ X one can associate the stalk O X,x := lim − →x∈U O X (U ) of "functions defined near x", a filtered colimit of rings and hence also a ring. If this ring is local (that is, has a unique maximal ideal) for every x ∈ X we say that (X, O X ) is a locally ringed space.
A fundamental construction in this area is the following. Given a ring R, let Spec (R) denote the set of its prime ideals. The Zariski topology is a natural topology on Spec (R): for I an ideal we define V (I) to be the prime ideals of R containing I, and the V (I) as I varies are the closed sets of Spec (R). We shall explain later how to use the theory of localisations of rings to construct a presheaf of rings O R on Spec (R) and to prove that it is a sheaf. The ringed space (Spec (R), O R ) is locally ringed, and is called the affine scheme associated to the ring R.
A scheme is a locally ringed space (X, O X ) with the property that X can be covered by opens U i such that the induced locally ringed space If R is a ring then Spec (R) is a scheme, because it can be covered by the open affine subset U = Spec (R).
To KB's naive eyes in 2017, everything here looked straightforward. But in fact there were several gotchas involved in turning this into a formal definition. The rest of this paper describes them, and how they were dealt with in Lean.
3. The first definition.
We begin with a discussion of localisation, and the construction of the sheaf of rings on the topological space associated to a ring. Let R be a ring and let S be a submonoid of (R, ×) (for some reason mathematicians often call S a "multiplicative subset"; it contains 1 and is closed under multiplication so it is precisely a submonoid). The localisation R[1/S] of R at S is a ring equipped with a canonical map i : R → R[1/S] and having the following universal property: for any ring A and any map f : The special case where S is the submonoid {1, f, f 2 , f 3 , . . .} generated by f ∈ R has its own notation R[1/f ].
Standard arguments involving universal objects show that R[1/S] is uniquely defined up to unique isomorphism, if it exists. In fact, these latter arguments do not even assume that S is a submonoid; in general the localisation at a general subset S of R is the localisation at the submonoid of R generated by S. Existence is shown by an explicit construction: one puts an appropriate equivalence relation on R × S (an element (r, s) is thought of as representing the fraction r/s) and puts a ring structure on the quotient. All of this was formalised in Lean with little fuss.
The construction of the topological space Spec (R) was equally uneventful. Next, a decision had to be made about how to put a sheaf of rings on Spec (R); there are several constructions in the literature. The prevailing philosophy of KB at the time was "always follow the Stacks project". 2 The approach in the Stacks project is as follows. Let X be a topological space. In [Sta21, Tag 009H] it is explained how to set up the theory of presheaves and sheaves on a basis for the topology on X, and in [Sta21, Tag 009N] it is shown how to extend a sheaf on a basis for X to a sheaf on X. Formalisation of these results, and their extension to sheaves of rings, was straightforward. 3.1. Definition of O X (D(f )), and "canonical maps". This was a part of the story where things did not go as smoothly as envisaged. The first problem was this. Say R is a ring, and f, g ∈ R have the property that D(f ) = D(g), that is, a prime ideal contains f if and only if it contains g. This can certainly happen in non-obvious ways -for example if x ∈ R and f = again with no definition of "canoniquement") and in 1.3.3 we see "un homomorphisme canonique fonctoriel M f → M g ", and the first usage of "M f = M g " to denote a "canonical" isomorphism rather than a set-theoretic identity. Having This becomes an issue in Lean, because in our formalisation we have rings R[1/f ] and R[1/g] which are most definitely not equal; certainly the universal property gives isomorphisms between them, but one of these rings is a quotient of R × {1, f, f 2 , f 3 , . . .} and the other is a quotient of R × {1, g, g 2 , g 3 , . . .}. If you like to think set-theoretically, you can think of an element of R[1/f ] as being a subset (an equivalence class) of R × {1, f, f 2 , . . .} and an element of R[1/g] as being a subset of R × {1, g, g 2 , . . .}. In particular, R[1/f ] and R[1/g] are visibly not equal.
One solution to this problem would be to throw the axiom of choice at it. For each open set U ⊆ Spec (R) which is known to be of the form D(f ) for some f (possibly infinitely many), we choose some "special" f U such that U = D(f U ) and define O X (U ) := R[1/f U ]. This of course works, but we envisaged that this definition would be frustrating to work with down the line.
Reid Barton on the Lean chat suggested the following approach instead, which was what we ultimately chose. If the open set U is known to be of the form D(f ), then define S U to be the submonoid {g ∈ R | U ⊆ D(g)} of elements of R which are non-zero on U , and define O X (U ) := R[1/S U ]. This has the advantage that no choices are involved; it bears the hallmark of a construction in constructive mathematics, where a rule of thumb is that if you can't figure out a natural way to choose one object from a set, then choose all of them.
This defines a presheaf of rings O X on the basic open subsets D(f ) of Spec (R), and by taking limits one can extend this definition to give a presheaf of rings on all of Spec (R). Amusingly, we then realised that to define schemes, this presheaf construction was all we needed.
3.2. Defining schemes. We defined a scheme to be a topological space X equipped with a sheaf of rings O X , for which X had a cover X = i U i such that each U i was isomorphic to Spec (R i ) for some ring R i . This isomorphism is in the books usually stated as an isomorphism of locally ringed spaces. However a locally ringed space is just a topological space equipped with a presheaf of rings and satisfying some extra axioms, so in particular an isomorphism of locally ringed spaces is the same as an isomorphism of spaces equipped with presheaves of rings. We have already defined a presheaf of rings on Spec (R), so we are almost done. It remains to define the pullback presheaf of rings on U i , and this is easy: if ι : It was straightforward to check that ι * O X is a presheaf of rings on U i , and our definition of a scheme was complete. Note that we did not need to demand that our original ringed space was locally ringed -this follows from the fact that it is locally affine. In particular, our definition is mathematically equivalent to the usual definition, although the proof of this involves theorems which were not at this time formalised.
Our original definition was met with some scepticism by the computer scientists in the Lean community, however, and not for this reason above. A definition with no unit tests might contain an error. It was suggested that we prove a theorem about schemes, to provide evidence that our definition was correct. We decided to prove the theorem that an affine scheme was a scheme. Although the result sounds trivial, some work remains: a scheme is a space equipped with a sheaf of rings, and we have thus far only equipped Spec (R) with a presheaf of rings. To prove that affine schemes are schemes should be essentially equivalent to proving that the presheaf O X of rings on Spec (R) is a sheaf.

3.3.
Proving O X is a sheaf on Spec (R). Again, we followed the Stacks project. Here we ran into a serious technical issue, and one might even argue that this issue is typically overlooked in the literature -it seems to be a very good example of a situation where mathematicians pay no attention to the details of what is happening, knowing that things are going to work out. When formalising, one has to check these details.
Let Step 2: One can now translate the statement into a purely ring-theoretic lemma [Sta21, Tag 00EJ].
We proceeded in reverse order, with CH proving the ring-theoretic lemma first. Let us state it here: Lemma 3.3.1 (Tag 00EJ). Let R be a ring, and say f 1 , f 2 , . . . , f n ∈ R generate the unit ideal. Then the following sequence is exact: Here the map α is the obvious one, and the map β sends r i to the element whose (i, j) component is It was only after we applied this to make progress with Step 1 that we understood the subtleties in what was left. The "canonical" identification of basic opens in Spec (R[1/f ]) with basic opens in Spec (R) involved, when identifying global sections, an identification of Of course these rings are canonically isomorphic, but they are not equal. In short, we had a proof of exactness of and we needed 3 a proof of exactness of To a mathematician, essentially nothing needs to be done here. A mathematician might say "the diagrams are the same; one is exact, so the other is" and this would be an acceptable proof.
Pressed for more details, a mathematician might offer the following explanation: Here all the vertical maps are canonical and all the horizontal maps are defined in a natural way and hence the squares will all obviously commute.
However in Lean this needs to be checked! Lean has no concept of what it means for an isomorphism to be canonical (and looking at the Wikipedia page on canonical maps one indeed discovers that there seems to be no formal definition of the word), and we needed to explicitly check that the squares in the above diagram commute.
So it came to pass that one line in the Stacks project tag 01HR ("Thus we may apply Lemma 10.22.2...We conclude that the sequence is exact") became several hundred lines of Lean code. In retrospect it would have been much easier to do a diagram chase. However we had a belief that "everything would follow immediately from the universal property" and instead went down this route, which was more troublesome than one might expect, because for example the homomorphism β above is not a ring homomorphism and hence the universal property cannot be used! We ultimately resorted to proving a lemma showing that there was at most one R-algebra map from R[1/S] to R[1/T ] and used this to finish. We proved that the squares commuted, and deduced that the presheaf of rings on Spec (R) was a sheaf. Our goal of proving that affine schemes were schemes was now in sight. In particular, in a univalent system, the ring isomorphism R[1/f g] ∼ = R[1/f ][1/g] can be promoted to an equality (for this richer concept of equality) and now it looks on the face of it that a rewrite would be able to make progress. However, univalence does not solve the problem which we encountered here. After the substitution in a univalent system, we would have a proof of exactness of one diagram, and we want to prove exactness of another diagram, and the diagrams now have the same objects, however we need to check that they have the same morphisms! Checking this of course boils down to checking that the squares commute, so the lion's share of the work still needs to be done. In our original definition of a scheme, we did the diagram chase "manually". However in our second iteration of the definition, we will introduce ideas which enable us to avoid this rewriting problem completely.
3.5. Affine schemes are schemes. With the proof that Spec (R) is a ringed space, we can now attempt to prove that it is a scheme. This provided one final surprise in our formalisation, and again Reid Barton explained the way around it. Our cover of Spec (R) by affines is just the identity map ι : Spec (R) → Spec (R), and all that remains is to show that the presheaves O X and ι * O X on Spec (R) are isomorphic. This boils down to the following: if U is an open subset of Spec (R) then we need to produce an isomorphism between O X (U ) and O X (ι(U )) which commutes with restriction maps.
Our first attempt to do this was the following. Note that ι is the identity map. Hence ι(U ) = U , and thus O X (ι(U )) = O X (U ). Let's define the isomorphism to be the identity map. Checking that the diagrams commute should then be straightforward.
But it was not straightforward; one now has to check that ρ ι(U)ι(V ) = ρ UV , and replacing ι(U ) with U in a naive manner caused Lean to give motive is not type correct errors. Ultimately we were able to get this working, but what is going on here? Mathematically there seems to be no issue.
We learnt from Mario Carneiro what the problem was. The fact that ι(U ) = U is a trivial theorem, but, perhaps surprisingly, it is not true by definition. The definition of ι(U ) is that it is the set of x ∈ X such that there exists u ∈ U with u = x. Hence in particular x ∈ ι(U ) ⇐⇒ x ∈ U (this is true by definition), and hence ι(U ) = U , because two sets are equal if and only if they have the same elements (this is the axiom of set extensionality). We have proved that ι(U ) = U , but along the way we invoked an axiom of mathematics and in particular the equality is not definitional. This means that rewriting the equality ι(U ) = U can cause technical problems with data-carrying types such as O X (ι(U )) which depends on ι(U ) (although in our case they were surmountable). This is a technical issue with dependent type theory and can sometimes indicate that one is working with the wrong definitions.
Fortunately, in our case, Reid Barton pointed out the following extraordinary trick to us: we can define the map O X (ι(U )) → O X (U ) using restriction rather than trying to force it to be the identity! Using restriction means that we need to supply a proof that U ⊆ ι(U ), but this is trivial (and who cares that it uses an axiom, we are not trying to rewrite anything). The fact that the diagram commutes now just boils down to the fact that restriction from ι(U ) to V via U equals restriction from ι(U ) to V via ι(V ), which follows from the presheaf axiom of transitivity of restrictions. This is certainly not the way that one would usually think about this, but it works fine.
3.6. Conclusions. The main problem with this first approach was the issue with localisations. The ring R[1/S] was defined as an explicit ring, and theorems were proved about it; later on when it came to apply these theorems, it turned out that in our application we only had a ring isomorphic to R[1/S] rather than our explicit definition on the nose. These issues were solved in our second approach.

The second definition.
Apparently there's a saying in computer science: "Build one to throw away". Having done this, we now knew what we should be doing; we had to develop a better theory of localisation. We now describe how we did this. 4.1. Localisation. The error we had initially made was to only define "the" localisation R[1/S] of a ring R at a submonoid S. The localisation is defined up to unique isomorphism, but pinning it down as an explicit set (or more precisely an explicit type, as Lean uses type theory rather than set theory) turned out to be a bad idea. What we needed instead is a predicate is localisation by S on ring homomorphisms R → T , saying that R → T is isomorphic to R → R[1/S] in the category of R-algebras, or in other words that T is isomorphic to R[1/S] in a manner compatible with the R-algebra structure. We will refer to this predicate by saying that the R-algebra T is a localisation of R at S, as opposed to "the" localisation of R at S. AL noted that in fact localising rings at submonoids was not the primitive notion: in fact, as Bourbaki taught us, one should be localising monoids at submonoids, and attaching ring structures later on. AL developed an entire formalised theory of localisation of monoids, with both the "explicit" constructions M [1/S] and the "predicate" approach, showing that the explicit constructions satisfied the predicate, and proving universal properties both for the explicit construction and the predicate construction. These files now form the foundation of the theory of localisation in mathlib.

4.2.
The sheaf on an affine scheme, again. RFM rewrote schemes from scratch, tidying up the code along the way and also moving away from the disastrous design decision of calling Lean files by their Stacks project tags (tags should be mentioned in docstrings, not filenames; filenames serve a useful organisational purpose). The refactoring to using predicates instead of explicit constructions meant that there was no longer any need to make the substitution of R[1/f ][1/g] into a lemma explicitly naming R[1/f g]; all one has to do is to prove that R[1/f ][1/g] satisfies the predicate for being a localisation of R at the submonoid generated by f g, which is straightforward. This shortened the definition by hundreds of lines of code.
The hard work, or so we thought, would be in reproving the ring-theoretic lemma [Sta21, Tag 00EJ] (Lemma 3.3.1) in this more general form. The issue here is that CH's original formalisation was an explicit computation involving the rings R[1/f i ] and R[1/f i f j ]; what we now needed was to reprove this lemma for all rings satisfying the localisation predicate instead. The beefed-up lemma would then apply in situations where the original lemma did not, meaning that the diagram chase described in section 3.3 would no longer be necessary. These definitions are mathematically equivalent, so to a mathematician they may as well both be the definition. However Neil Strickland proposed a third definition: Definition 3 (Strickland). An R-algebra f : R → T is a localisation of R at S if it satisfies the following three conditions: • Every t ∈ T can be written as f (r)/f (s) for some r ∈ R and s ∈ S; • The kernel of f is the annihilator of S.
It is not difficult to prove that Strickland's definition of the predicate is equivalent to the other two. Indeed an explicit computation using the explicit construction of R[1/S] as a quotient of R×S shows that it satisfies Strickland's predicate, and conversely any R-algebra T satisfying Strickland's predicate admits a map from R[1/S] (by the universal property and the first condition), which can be explicitly checked to be surjective (from the second condition) and injective (from the third condition).
So which definition should one use? This is not a mathematical question, it is what is known as an implementation issue, or a design decision. Ultimately of course the goal is to prove that all of the definitions are equivalent. But where does one start? One would like to fix one of them and then develop an interface, or API, for it. This is a collection of basic theorems about our predicate (some deducing it, some using it) which will ultimately lead to a formal proof that it is equivalent to the other two definitions. In particular, one will sometimes have to verify the predicate, and one will sometimes have to use it.
Strickland's predicate had advantages over the other two definitions when it comes to using it. In particular, it does not involve quantification over all rings. Using a property involving quantification over all rings often involves having to construct a ring with nice properties and then applying the universal property to that ring. For example, we invite the reader to prove that any R-algebra T satisfying the universal property of being a localisation (definition 2) also has the property that the kernel of R → T is the annihilator of S. The shortest way we know how to do this from first principles is to first show that the explicitly constructed ring R[1/S] satisfies the universal property, secondly to prove that two rings satisfying the universal property are isomorphic as R-algebras, and finally to do an explicit calculation of the kernel of the map R → R[1/S] to prove the result. Of course there is no problem formalising this proof, but it gives an idea as to how much work it is to build an API for definition 2.
Ultimately one has to fix one definition of the predicate, and then prove that it is equivalent to the other two; there will always be some work involved. But "API building" turned out to be easiest with Strickland's definition, which is the one RFM used. 4.4. Reproving 00EJ. What remains to be done is to reprove Lemma 3.3.1 not for our rings R[1/f ] but more generally for rings satisfying Strickland's predicate. To our surprise, this turned out to be very easy. Indeed, the only facts about the R-algebras R[1/S] used in the Stacks project proof in 2017 4 were precisely the ones isolated by Strickland! The refactoring was hence far easier than expected. In some sense, what happened here was that we made the statement of the lemma more general, and noted that the same proof still worked. 4.5. Definition and usage. RFM also set up the theory of locally ringed spaces, enabling us to define a scheme as a locally ringed space which was locally affine. The proof that an affine scheme is a scheme now also needs a new proof, namely that the stalks of O X were local rings. This needed some of the theory of filtered colimits, but this did not present any particular problems.
KL used the definitions of the project in this form to do the "gluing sheaves" Exercise II.1.22 in Hartshorne's algebraic geometry textbook [Har77] and also to prove that Spec was adjoint to the global sections functor on locally ringed spaces [Sta21, Tag 01I1]. However when it came to start thinking about porting our definition into Lean's mathematics library, we ran into a problem. Part of our code was still sub-optimal: we had a definition of a sheaf of types, and a definition of a sheaf of rings. These notions should be unified under some more general notion of a sheaf of objects in a category. Thus the third definition was born.
5. The third definition: sheaves done correctly.
5.1. Category theory in mathlib. SM has been the main driving force behind a gigantic category theory library in Lean. In early 2018, a combination of his work not yet being mature enough, and there not being much infrastructure to support easily working on branches of mathlib, meant that we had developed our own definitions of sheaves rather than using category theory. By 2020 this was no longer the case, and SM's definition of a presheaf taking values in a category was the natural thing to use for the "official" definition of a scheme. We had seen with our own eyes the problems of having one definition of presheaves of types and another definition of presheaves of rings -we were constantly having to prove results for presheaves of types and then prove them again for presheaves of rings. Ultimately we had to completely refactor the sheaf part of the story, but we took this opportunity to introduce category theory more generally. Another advantage of the third definition is that rather than working in a new project with mathlib as a dependency, we worked directly on a branch of mathlib, and ultimately the code ended up as part of mathlib meaning that it will not quickly rot and die, as is very very common with Lean code which is not in mathlib (mathlib is not backwards compatible -it is still in some sense an experimental library and occasionally big design decisions are changed in an attempt to make it better).

5.2.
Changes made to the definition. We go through the final definition, pointing out how it differs from the previous version. In this definition, a scheme is an object in the category LocallyRingedSpace which is locally isomorphic to an affine scheme. The abstract nonsense presented no surprises; the work left, when defining a scheme and proving that affine schemes are schemes, is to define the sheaf of rings on Spec (R) in this language. This time it was decided to not follow the Stacks project approach via sheaves on a basis, but to instead define the sheaf directly following [Har77], where an element of O X (U ) is a dependent function taking u ∈ U to an element of R u , the localisation of R at the prime ideal u, subject to the condition that locally the function can be written as r/s with r, s ∈ R and s not vanishing near u. The advantage of this approach is that it is clear that O X is a sheaf; the ring-theoretic Lemma 00EJ is not used at all in this approach. Indeed, in this set-up, 00EJ is used to prove O X (Spec (R)) = R.
5.3. Sheaves and categories. SM defined the notion of a sheaf on a topological space taking values in any category which has products. The sheaf condition on a presheaf is that the usual "sheaf condition diagram" is an equalizer. It is then a theorem that a sheaf of rings is a presheaf of rings whose underlying presheaf of types is a sheaf of types. Since then, Bhavik Mehta has defined the concept of a sheaf of types on an arbitrary site, and more generally the notion of a sheaf of objects of an arbitrary category on a site. All of this work is now in mathlib. These definitions open the door to defining and proving theorems about theétale cohomology of schemes in Lean.

5.4.
A word on mathlib. We mentioned above that this definition of a scheme made it into Lean's mathematics library mathlib, which means that all the code in it was subject to scrutiny by the library maintainers. A reasonable analogy would be that mathlib is like a journal, and the maintainers are like the editors. After three iterations of the definition of a scheme, it was in good enough shape for a "pull request" to be made to mathlib. (A pull request is the open source project equivalent of submitting an article to an editor!) Note that the multiple iteration procedure discussed in this paper is not usual -but we were beginners in 2017 with very little information to guide us on how to make schemes on a computer, and KB's poor initial design decisions were because of this. Nowadays we have a much better understanding of how to put modern mathematics into Lean's dependent type theory.
The advantage of getting the definition into mathlib is that now it is guaranteed to compile for the duration of Lean 3's lifespan, because if someone makes changes to the library which break it, it will be down to that same someone to fix it. This is in stark contrast to the first two definitions, which compile with very old versions of Lean and mathlib, and would almost certainly not compile with modern versions.