The content in ring theory provides results on the spectrum of a quotient ring and reaches the result that the spectrum of a quotient ring is homeomorphic to a closed subspace of the spectrum of the original ring (in Zariski topology).

I have to say Daniel’s new theory on Finite State Machines was quite a surprise for me as the subject is quite far away from what I associate with mathematics that is easy to formalize is set theory. The material reaches the proof that non-deterministic finite state automata determine the same languages as deterministic finite state automata.

]]>Let be the set of ideals of some commutative ring and be the set of prime ideals (i.e. the spectrum) of that ring. As it turns out the collection is then a topology, called *Zariski topology*.* *The carrier of this topology is and the closed sets are of the form for . So this notion belongs to algebraic topology but unlike for the topological groups or rings the topological structure is completely derived from the algebraic structure. Each ring has its Zariski topology.

Metamath is considered a “low level” language and proof assistant, so I recently got curious how the Metamath proofs would compare with similar proofs written in the Isar dialect used in IsarMathLib. In this release I manually translated the Metamath’s utopreg theorem together with a couple of dependencies, taking advantage of Isabelle automation features to the extend I usually do in IsarMathlib. The following table compares verbosity of the original and translated proofs for the theorems whose proofs expressed similar ideas:

Theorem | Steps Metamath | Lines IsarMathLib | Factor |

utopreg | 95 | 52 | 1.8 |

utopsnneip | 15 | 14 | 1.1 |

ustex3sym | 25 | 11 | 2.3 |

imasncls | 64 | 28 | 2.3 |

utop3cls | 103 | 27 | 3.8 |

On average IsarMathLib proofs were about 2.3 times shorter. I have to say I expected that factor to be somewhere between 3 and 4.

The original Metamath *utopreg* theorem states that all Hausdorff uniform spaces are regular. After I translated the proof I was surprised to notice that the IsarMathLib’s version does not reference the hypothesis that the uniform space is Hausdorff. So, the IsarMathLib version shows that all uniform spaces are regular. I am not sure how it happened. To be honest I was not able to follow the Metamath proof exactly – it’s just too many small steps for me to put in my head at the same time. I was translating the proofs by first showing the steps marked green in Metamath Proof Explorer (I understand this indicates that the theorem referenced in the step is recent and hence close to the one being shown). Then I looked at facts made available this way and tried to figure out how one can get to the thesis of the theorem from them. It is possible that the Metamath proof does not make real use of this hypothesis as well, it’s just easier to spot in Isar.

We have a server and some unknown number of clients, possibly on different hosts. The clients send messages to the server, some of them only to say “Hi”. The server responds with a message containing an integer which says how many times the server received the “Hi” message so far. What is the minimal amount of F# code one can write to implement this (i.e. both server and client)?

There are a couple of ways to do IPC (Inter Process Communication) in F# (or C#). One can use named pipes or gRPC, but in this post I want to present Fable.Remoting.

The Fable project is best known for its F# to JavaScript compiler – the home page has the title “Fable – JavaScript you can be proud of”. This is about to change though – they are working on other target languages, so soon it might be “Fable – JavaScript, Python, Rust, Dart or TypeScript you can be proud of”. The Fable.Remoting sub-project used to implement the browser-server communication but since the dotnet client was added it has become a convenient mechanism for doing IPC between applications written in F#.

The first step of the exercise is to set up a solution with two projects: `FableServer`

and `FableClient`

:

In the `FableServer`

project we add a package reference to `Fable.Remoting.Suave`

which is the Fable.Remoting server based on the Suave web server.

The next step is to add an F# source file that defines API functions and types. This file is shared between the server and client projests. In this exercise the file consists of just three lines:

The `Api`

type is a record with fields holding the functions that our API will expose. In this case there is only one. The return types of those functions have to be wrapped in `Async`

.

Typically this file contains some custom types that are used in the API calls. We don’t have any custom types as the only function of the API takes a string as the only parameter and returns an integer option.

Now let’s do the server code. We start with couple of imports:

To count the “Hi” messages in a thread safe way we use the F# counter factory idiom

Now `countHi`

is a function that when called will increment the counter and return its new value.

Next we define our API as an instance of the `Api`

type defined in the shared file:

Then some Suave – related magic:

And finally the code that starts the server

That will be all on the server – about 30 lines.

On the client we start with imports:

Note the shared module `ApiDefinition`

has to be here.

Next we define where the server is. The default config of the Suave server (that we used in the server code) listens on port 8080:

Next there is the `Async`

task that sends the “Hi” message to the server:

And finally the code that will execute that task five times with 1s breaks in between:

That’s it on the client – about 20 lines of code, bringing the total to about 50 lines. I wonder how would the solutions using named pipes of gRPC compare in terms of size.

Btw, in KDB/q the solution to this exercise takes 2 lines – one on the server an one on the client. I think it would be interesting to have a set of a hundred or so small challenges like this that are likely to result in at least an order of magnitude of difference in code size between solutions written in different languages. One can then reduce the dimensionality to 2 or 3 using PCA (or whatever people use these days) and have a way to visualize a comparison between languages in terms of type of tasks that can be done more or less easily in them.

]]>There is a little bit of formalized mathematics added in this IsarMathLib release as well. I added a couple of results from general topology that I always considered neat and elegant: a characterization of Hausdorff spaces as those for which the diagonal is closed in the product topology on , the fact that the graph of a function into a Hausdorff space is closed in and that two continuous functions into a Hausdorff space are equal on a closed set.

Another theorem added is related to abstract neighborhood systems. IsarMathLib had had a formalization of the fact that if one has a neighborhood system on one can construct a topology on and vice versa: starting from a topology we can define a natural neighborhood system. In this release I added a theorem asserting that if we start from a neighborhood system, create a topology from it, then create it’s natural neighborhood system, we get back the original neighborhood system.

]]>Haskell | F# | |

lines | 2026 | 1692 |

words | 10334 | 9239 |

characters | 72006 | 79320 |

The F# syntax is not as clean as Haskell’s so it was a surprise for me that the number of lines required was about 16% less in F# than in Haskell. Still, I would say that F# is slightly more verbose as the total number of characters was 10% higher in F#. Translating the parser of the subset of the Isar formal proof language that is used in IsarMathLib was almost mechanical and boring thanks to FParsec, which is the F# clone of Haskell’s Parsec parser library. I am especially happy with the result of that part of the project – the parsing errors were difficult to debug in Haskell. FParsec has better diagnostics built in – in case of failure it shows the backtracking information which helps a lot to pinpoint the problem in the text being parsed.

On the mathematics side in this release I have added a theorem stating that an ordered loop valued metric space is T_{2}.

I was looking for an interesting example of an ordered loop and I found that nonzero octonions with multiplication form a loop. Octonions are octets of real numbers with naturally defined addition and somewhat less naturally defined multiplication. John Baez, in his excellent exposition characterized octonions as “the crazy old uncle nobody lets out of the attic”. Octonions have applications in physics, although some people think it’s all just hype. I think about them as the next step in the progression *real numbers complex numbers quaternions*. When we go from complex numbers to quaternions we loose commutativity of multiplication, when we go from quaternions to octonions we loose associativity. This makes nonzero octonions a proper loop, more specifically a Moufang loop. To get an ordered loop we can define the partial order on nonzero octonions by setting iff or perhaps if one wants to have the set of the positive element inside of the unit ball.

One stumbling block that I encountered was related to the way a SchemaElement is encoded in Parquet. A SchemaElement is a struct with a couple of fields selected from a fixed collection. The fields have numerical identifiers which are not provided directly but through deltas between their values. To obtain actual field id one has to compute the sum of the deltas provided (as 4-bit integers) in the file. For a while it was unclear if there is a way to encode such sum in Kaitai Struct and there was an issue about it on Kaitai GitHub repository opened more that four years ago. However, some three weeks ago cher-nov came up with a solution to this problem and posted it to the issue linked above. In this post I want to present an application of this solution to a toy format as another example that one can look at.

Suppose we have a binary format that represents information about a car. The information consists of a bunch of fields, each encoded as two bytes. The first byte of a field description provides the field id and the second one is a code for the field value. The Kaitai Struct specification for such straightforward format is as follows:

```
meta:
id: car
instances:
car:
type: field_t
repeat: eos
types:
field_t:
seq:
- id: field_id
type: u1
enum: field_name
- id: field_val
type: u1
enums:
field_name:
1: model
2: make
3: color
4: engine
5: age
6: price
```

Here the *enums* element provides a mapping from numerical values of field id’s to the their readable names. For example a sequence of bytes `01 02 03 14 05 21 06 12`

is parsed by Kaitai Web IDE as follows:

Now consider a situation when the field id’s are coded as deltas (increments). So, the same information as before is coded as a sequence of bytes `01 02 02 14 02 21 01 12`

and the actual field id’s are obtained by summing up the values `01 02 02 01`

. Then the Kaitai Struct code that does this is as follows:

```
meta:
id: sum_reduce_pattern
instances:
car:
type: field_t((_index == 0) ? 0 : car[_index-1].field_id)
repeat: eos
types:
field_t:
params:
- id: prev_field_id
type: u1
seq:
- id: field_id_delta
type: u1
- id: field_value
type: u1
instances:
field_id:
value: prev_field_id + field_id_delta
field_name:
value: field_id
enum: field_name
enums:
field_name:
1: model
2: make
3: color
4: engine
5: age
6: price
```

Kaitai Web IDE shows a bit more this time:

This example shows how Kaitai Struct can express (what is called in Haskell as) `scanl`

over a stream of bytes. In other words one can do `state -> update -> state`

style of programming in Kaitai Struct this way.

In other news, Pedro Sánchez Terraf announced that his team has completed a formalization of the independence of CH in Isabelle/ZF. This is a good news for IsarMathLib as well. Isabelle/ZF is used by very few people and I worry that at some point the Isabelle team stops supporting it, which would be the end of IsarMathLib. Every application like this makes it less likely.

]]>.

This shows that if we define a uniform space through a family of uniform covers then we can always get the usual definition by transforming that family into a uniformity.

The current release adds the dual fact (unicov_from_uniformity): if is a uniformity on then the following collection of covers of is a family of uniform covers:

.

The next two theorems show that these two transformations are inverses of each other.

I should probably quote sources for my formalization so that not to create an impression that I claim I am inventing some new stuff here. However the truth is that I found the Willard’s “General Topology” book that I bought for this nearly useless. So I ended up mostly getting definitions and facts from the “Uniform cover definition” section on the Wikipedia page on uniform spaces, and figuring out the proofs by myself. The only exception was a nice (even if not completely correct) proof that barycentric refinement of a barycentric refinement is a star refinement by Henno Brandsma that I found on Stack Exchange and converted to the `bary_bary_star`

lemma.

Carnegie Mellon received $20 million to establish a Center for Formal Mathematics. The gift was made by Charles C. Hoskinson, the founder of Cardano and co-founder of Ethereum. As one of the Carnegie Mellon officials said

“Charles’ generosity is helping us to make it possible for Lean mathematics to be more predominantly studied and to make it more accessible as an educational tool.”

It looks like “Lean mathematics” is becoming a synonym of “formalized mathematics” in a similar way as “google” has become a synonym of “search engine”. I can’t say I am happy about it.

Timothy Gowers twitted recently:

A. If you have formalized your proof in a language such as Coq or Lean, then you’ve definitely got a proof.

It is good to hear such assurance form a prominent mathematician. I was wandering what would happen if someone from outside of academia solved and important open problem. How helpful would it be to have a formalization to back up their claim in such case? For me a formally verified proof is more trustworthy and carry more weight than any peer reviewed one, but I have had an impression that this opinion is not common among mathematicians.

]]>Consider a set with its powerset (the set of subsets) . A collection of subsets of whose union is equal to is called a *cover* of . So, we can define the set .

For a set and a collection of of subsets of we can define the *star* of *in* as .

For two covers we say that the cover is a star-refinement of the cover and write if for every we can find a such that is contained in .

Finally we are able to define uniform covers. This notion is a bit tricky as there is really no separate notion of a uniform cover. If we look at cover of we cannot say if this is a uniform cover or not. What actually is defined is a *family* of uniform covers. A member of such family can only be called a uniform cover if it is clear from the context what family of uniform covers it belongs to.

A nonempty collection of covers of is called a *family of uniform covers* iff the following two conditions hold:

a) If , and , then

b) For every two covers we can find a cover that is a star-refinement of both and

This definition is slightly different that the one on the Wikipedia page on uniform spaces, which specifically requires that the trivial cover is a member of . However, since every cover is a star-refinement of the trivial cover and is not empty, condition a) implies that .

The key fact here is that if is a family of uniform covers of then the following collection of subsets of is a (diagonal) uniformity:

In words, is the collection of supersets of sets of the form as ranges over .

In Willard’s “General Topology” book the proof that is a uniformity is left as a “straightforward exercise” for the reader. Typically that means that the proof is long and tedious and the author does not feel like typing all that down. In this case the proof is indeed of mostly straightforward “follow your nose” kind right up to the moment when given a set one needs to find a set such that (here is the composition of relation with itself). For that, I found the following identity useful:

It took me some effort to figure out this identity and I was ready to type the proof of that in Isabelle, split into two inclusions etc. To my amazement though Isabelle accepted this fact without an explicit proof, only with the reference to the definition of star. This was probably the most unclear to me fact that was obvious to Isabelle that I have seen writing proofs for IsarMathLib so far. I left the proof of this identity as an exercise for the reader. This time the straightforwardness of this fact got certified by Isabelle.

Which brings us to the subject of

Ok, it’s grandfather’s story time. Long time ago and far away, when I was studying mathematics at the University of Tennessee, Knoxville, there was a very talented student from Romania there, let’s call him Gabriel P. Once I was struggling with a proof of some theorem and I asked him if he has an idea how to prove this thing. He looked at the problem, thought for a minute, then nodded his head, smiled and said “It’s true”. And left. I was more frustrated than enlightened and since then I am of opinion that automation in proof assistants is overrated.

Sure, automation is good for the writer as it reduces their effort. However, if there is too much of automation it affects the reader as it reduces the amount of information contained in the proofs. So there is a trade off with some optimum depending on writer’s goals. If the writer goal is certification of truth only, as is usually the case with software verification, then the more automation the better. In mathematics the issue of communication comes into play and the proofs are supposed to convey information on *why* an assertion is true.

Of course ideally the proofs would be built by a dialogue between a researcher and a proof assistant AI. The PA would then generate readable proofs in a structured proof language that processed by the presentation layer would allow a reader to set their desired level of detail, from high level bullet points down to the Metamath-style atomic steps. A couple of days ago I considered proof assistants like this such a remote possibility that it would not be worth it to even write this paragraph. This changed after I saw the Open AI Codex demo. I think now that proof assistants that do for crafting formal proofs what Open AI Codex does for programming are a couple of years off, at most.

]]>