Cipher 71: Monoalphabetic II

As promised, the fourth season of cp4space ciphers has now commenced. Here’s a monoalphabetic substitution cipher with a nine-letter plaintext containing a man’s name. The password for the solvers’ area is the person who killed that man, entirely in lowercase:

F B' U2 R2 L2 U D'


Posted in Ciphers | Leave a comment

Tweetable architecture

Quite probably the most world-renowned architect of the 21st century, Zaha Hadid, has been recently commissioned to design a new fluid dynamics exhibition in the London Science Museum. It will certainly add much more depth than its current collection of stellated polyhedra, which was the only particularly mathematical exhibit I recall from the last time I visited (8th April).

You’ll certainly want to view Alex Bellos’s gallery of the exhibition, and then read his Guardian article announcing it.

Zaha Hadid’s architecture is based upon a contemporary style known as parametricism, which rejects the ideas of straight edges and rigid forms, favouring more natural forms such as the minimal surfaces imitated by soap films and encapsulated in the forthcoming exhibition.

My personal favourite of her masterpieces, entitled Galaxy Soho and depicted above, always reminds me of the internal structure of a chloroplast, with columns of thylakoids joined by integranal lamellae.

Image courtesy of Kelvin Song.

Anyway, one of the features of parametricism is the use of mathematical formulae to design buildings. This is actually an extraordinarily good idea for at least three reasons. Firstly, from a merely engineering standpoint, optimal structures are usually described by simple equations, such as the catenary (optimal self-supporting arch). Secondly, from an aesthetic perspective, simple equations typically yield pleasing, sensual forms. Thirdly, using simple equations eliminates the need for pages upon pages of excruciatingly detailed instructions.

In fact, how simple can we get? The epitome of our modern requirement for brevity is Twitter, which limits individual posts to 140 characters in length. Would it be conceivably possible to tweet an architectural design?

Wolfram has recently released its Tweet A Program initiative, whereby one can instruct it via Twitter to execute arbitrary Mathematica programs of at most 128 characters (since “@wolframtap ” occupies the other twelve characters) in the cloud, tweeting the result back to you.

So I decided to tweet a 126-character program to plot a pair of twin towers on the chloroplast theme. And it came back with this:


It resembles a couple of caterpillars waltzing in lime-flavoured jelly. I’m sure you can do much better; just write a Mathematica program of at most 128 characters, tweet it to @wolframtap, and retweet your parametric architecture back to me at @apgox.

Posted in Activities | 3 Comments

Tributes to cryptanalysts

Earlier on cp4space, I mentioned how there were a couple of planned tributes to Alan Turing and Bill Tutte. Subsequently, both of these projects have since been completed.

Firstly, the premiere of A Man From The Future was performed by the Pet Shop Boys at the BBC Proms. An excerpt, entitled He Dreamed Of Machines, is available on YouTube:

This single is due to appear in the forthcoming biographical film, The Imitation Game.

Similarly, the Bill Tutte memorial has now been unveiled. The main sculpture is an arrangement of panels inspired by punched card, which display an image of Tutte when viewed from the correct perspective:

This is part of a larger initiative designed to increase awareness of W. T. Tutte through various events and a local scholarship.

Posted in Uncategorized | Leave a comment

Hyperbolic Minecraft

(Firstly, this is a test to see whether WordPress is configured to automatically link to cp4space posts as tweets from apgox. Hopefully it will succeed.)

Yesterday, I received a rather interesting e-mail from Tim Hutton, lead developer of the reaction-diffusion software Ready. It was concerned with a (possibly facetious) post by Mike Stay concerned with the possibility of implementing a disproportionately popular video game in hyperbolic space. I haven’t personally encountered the aforementioned game, although one of my colleagues mentioned at a barbecue that his children were obsessed with it.

To summarise, we needed a way to construct the {4, 3, 5} honeycomb of hyperbolic space (the dual of the order-3 tiling by dodecahedra) to use as an underlying grid for Ready. Fortunately, I realised that the intersection of the honeycomb with the xy-plane is merely the bog-standard order-5 square tiling, which meant that I could reduce it to an easy two-dimensional problem. With some slight help from Mathematica’s FullSimplify routine, I prepared the following recipe:

  • Define t = (1 – sqrt(7 – 3 sqrt(5)))/3.
  • Let the `central cube’ have vertices (±t, ±t, ±t).
  • We define six `mirrors’ to be the spheres with radius sqrt(3 – sqrt(5)) and centred on one of the following six vertices: (1, 0, 0), (0, 1, 0), (0, 0, 1), (-1, 0, 0), (0, -1, 0), (0, 0, -1)
  • Sanity check: the central cube is the volume containing the origin and enclosed by the six mirrors.
  • Produce images of the central cube by `reflecting’ in the mirrors to your heart’s content. By `reflecting’, I mean this:
  • So, to reflect p about the mirror with centre q, you apply the transformation p –> q + (p – q)*(R^2/|p – q|^2) where R^2 = 3 – sqrt(5) is the squared radius of the mirrored sphere, and p and q are vectors in $\mathbb{R}^3$.
  • The result should be the {4, 3, 5} tiling of a Poincare ball of some radius I can’t be bothered to calculate.

Miraculously, this ad hoc sequence of instructions actually worked, and Tim was able to construct the first couple of shells of the hyperbolic tiling. For instance, here is the tessellation after the second shell has been added:


So far, so good. However, there is the issue of avoiding duplicated blocks, which I addressed with the following (incredibly lazy) suggestion:

I would avoid duplicates by rejecting any new cubes whose centres coincide with existing cubes (by using a hashmap or something similar).

Often many problems in life reduce to the dichotomy of whether to `do maths’ or `use a hashmap’. I’ve decided to resort to the latter, by virtue of working for several weeks for a software engineering company. More diligent people actually design an elegant method of coordinatising hyperbolic space; one such mathematician is Maurice Margenstern, who wrote a paper addressing the two-dimensional analogue of this problem.

Anyway, Tim Hutton was satisfied with the hashmap solution, and this algorithm has since been incorporated into the Ready code (c.f. relevant section of the Subversion repository). As a preliminary trial, here is a Ready screenshot of an experiment with the Gray-Stott reaction-diffusion system running on the {4, 3, 5} tiling of hyperbolic space:



Anyway, Tim decided to contribute an OEIS sequence containing the numbers of cubes within a distance of at most n from the central cube. Slightly more naturally, this sequence can be regarded as the partial sums of this sequence (which counts the number of cubes in each layer):

1, 6, 30, 126, 498, 1982, 7854, 31008, 120666, ...

Similar sequences have been created for two-dimensional tilings. Indeed, the order-3 heptagonal tiling has the remarkable property that the number of tiles in each layer is seven times a Fibonacci number:

Specifically, if we divide the number of tiles in each layer by seven, we obtain the sequence (1, 3, 8, 21, …), which are alternate Fibonacci numbers. Similarly, a three-dimensional honeycomb is dictated by a third-order linear recurrence relation; unlike its dual tiling, this happened to be in the OEIS.

Posted in Uncategorized | 3 Comments

First female Fields medallist

Tomorrow, this year’s Fields medals were awarded*. The four recipients of this prestigious quadrennial accolade have made profound advancements in their respective areas of mathematics, specifically:

  • Artur Avila has revolutionised the study of dynamical systems, proving many hitherto open conjectures in the field. This is exciting from both a pure perspective, augmenting our understanding of the ergodic theory of various systems; and from an applied point of view, giving a deeper insight into the behaviour of chaotic systems such as phase transitions.
  • Manjul Bhargava‘s research massively generalises Gauss’s composition law, as well as enabling one to enumerate rings of finite rank with a particular discriminant. This has subtle connections to the theory of algebraic curves, including new bounds on the average rank of elliptic curves.
  • Martin Hairer made extremely notable discoveries about stochastic partial differential equations, which generalise PDEs by including the effects of random noise. In doing so, he has provided solutions to many new families of SPDEs, several of which have physical interpretations.
  • Finally, Maryam Mirzakhani has contributed immensely not only to the geometry of Riemann surfaces and their moduli spaces, but also their dynamics. Incidentally, she is the first female Fields medallist (whilst several great female mathematicians flourished in the twentieth century, including Emmy Noether, Julia Robinson and Ruth Lawrence, the award remained elusive until now), and the remainder of this article is dedicated to her outstandingly brilliant accomplishments.

*International Date Line.

Maryam Mirzakhani

Her work is concerned primarily with compact Riemann surfaces of a given genus. From a merely topological perspective, these are multi-holed tori. Riemann surfaces, however, are endowed with a complex structure and therefore a natural metric, which is much deeper and more interesting.

With the exception of the trivial cases of the sphere and torus, these compact Riemann surfaces are quotients of the hyperbolic plane (c.f. Uniformisation Theorem). These quotient spaces are really exciting, and admit an intuitive classification thanks to Thurston’s beautiful theory of orbifolds. Maryam’s early work established a formula for the number of simple closed geodesics on these Riemann surfaces, together with asymptotics for their lengths.

Her next advancements were related to the moduli spaces of Riemann surfaces.

Moduli spaces

So, what’s a moduli space? It’s probably easiest to explain in the genus-one case, which is simple enough to understand, without being completely trivial. Recall that we can obtain a torus by taking a parallelogram and associating edges. Or equivalently by taking the plane and quotienting by a lattice:


In choosing the fundamental parallelogram, we have a huge amount of freedom. Both the red pair and blue pair of vectors above generate the same lattice, and therefore describe geometrically identical tori.

Now, we can consider the four-dimensional parameter space of fundamental parallelograms (i.e. the space of points (x, y, z, w), corresponding to the parallelograms generated by the vectors (x, y) and (z, w)). At the moment this is just plain old \mathbb{R}^4, but it is more geometrically meaningful to identify points that describe the same lattice. The resulting quotient space, the moduli space, is a four-dimensional manifold.

Observe that rotating and scaling the two vectors results in geometrically similar lattices (therefore geometrically similar Riemann surfaces). We can consider a further quotient of this four-dimensional space, namely a two-dimensional orbifold. You may recognise this as being the quotient of the upper half-plane by the action of the modular group, or the fundamental region of Klein’s j-function:

So, that’s basically what a moduli space is. Maryam discovered a formula for the volume of moduli spaces of a particular genus, resulting in a remarkably elegant new proof of Witten’s conjecture.


Not merely content with providing a marvellous insightful proof about the geometry of moduli spaces, she decided to investigate their dynamics! Firstly, she demonstrated the ergodicity of Thurston’s ‘earthquake deformation’ of hyperbolic space, which is certainly no mean feat!

Ergodic theory is largely concerned with the topological closure of orbits of points. For example, if we take a geodesic on a torus, it will either form a closed loop (e.g. a torus knot) or an irrational cable:

This is a dense subset of the torus, so its topological closure is the torus itself. On more complicated manifolds, such as the moduli spaces considered by Mirzakhani, the topological closures of geodesics can be infinitely intricate fractal structures.

In a similar vein to how holomorphic functions are much more well-behaved than real analytic ones, Mirzakhani settled a long-open conjecture and proved that closures of complex geodesics are always algebraic subvarieties (which are smooth and tame, unlike the pathological fractals that arise in the ergodic theory of real geodesics).

Posted in Uncategorized | 2 Comments

How to do geometry properly

For literally thousands of years, people have been writing books about elementary geometry. Many of these, such as Bradley and Gardiner’s Plane Euclidean Geometry, are concerned with solving problems in Euclidean geometry. They are subsequently bought by many adolescents intending to compete in the International Mathematical Olympiad.

This is completely pointless.

We shall instead explore Tarski’s cool, slender, axiomatic approach to geometry. This has numerous advantages over the cumbersome alternatives:

  • Simplicity: there are only three concepts, namely the idea of a ‘point’ and the relations of ‘betweenness’ and ‘congruence’. These could be understood by the entire populace of the Clapham omnibus.
  • Brevity: memorising hundreds of definitions, lemmas and theorems will provoke a reaction of ‘tl;dr‘ from all but the most hardened tediophiles. Fortunately, Tarski only has eleven axioms which rest on top of the seven axioms and two inference rules of first-order logic.
  • Decidability: we can algorithmically decide whether or not a statement is true, and provide a perfectly rigorous proof without all of that mucking about with diagram dependency.
  • Innumeracy: no arithmetic is required, let alone algebra.

So, without further ado, we shall introduce the framework. To make this entirely self-contained (and therefore giving geometry textbooks an unfair advantage, since they assume knowledge of concepts such as algebra) we shall include first-order logic here.


The language is an especially simple one, in that it is first-order and involves no function symbols. It is constructed inductively as follows:

  • Variables are typically written as lowercase letters, such as x and y, and understood to represent geometrical points. We allow the use of the prime symbol to enable an unbounded number of variables with a finite alphabet (such as x‘, x”, x”’, x”” and so on).
  • Atomic formulae are expressions of the following form (where wxyz are variables):
    • (xy), (read as ‘x and y are the same point’);
    • B(xyz), (read as ‘y lies on the line segment with endpoints x and z‘);
    • C(wx, yz), (read as ‘the distance between w and x is the same as the distance between y and z‘);
    • ⊥, (read as ‘false’).
  • Formulae are constructed inductively in terms of atomic formulae:
    • Every atomic formula is a formula;
    • If P and Q are formulae, then so is (P ⇒ Q) (read as ‘P implies Q’);
    • If x is a variable and P is a formula, then (∀x.P) is a formula (read as ‘for all x, P is true’).
  • Sentences are formulae in which every variable is bound (every variable x is enclosed within the scope of a ∀quantifier).

That is all.


Axioms are formulae which are assumed without proof. Firstly, we have seven logical axiom-schema:

  1. Axiom K: for all formulae P and Q, the formula (P ⇒ (Q ⇒ P)) is an axiom.
  2. Axiom S: for all formulae P, Q and R, the formula ((P ⇒ (Q ⇒ R)) ⇒ ((P ⇒ Q) ⇒ (P ⇒ R))) is an axiom.
  3. Double negative elimination: for every formula P, the formula (((P ⇒ ⊥) ⇒ ⊥) ⇒ P) is an axiom.
  4. Reflexivity of equality: for every variable x, the formula (∀x.(xx)) is an axiom.
  5. Instantiation of equality: if x and y are variables, and P is a formula not containing ∀y, then (∀x.(∀y.((xy) ⇒ (P ⇒ P[y/x])))) is an axiom, where P[y/x] is the formula obtained by replacing every instance of x in the formula P with y.
  6. Universal instantiation: if x and y are variables and P is a formula, then (∀x.(P ⇒ P[y/x])) is an axiom.
  7. Seventh axiom: if x is a variable and P and Q are formulae, with x not occurring unbound in P, then ((∀x.(P ⇒ Q)) ⇒ (P ⇒ (∀x.Q))) is an axiom.

These are augmented with eleven geometric axioms:

  1. Reflexivity of congruence: (∀x.(∀y.C(xyyx))) is an axiom, which is logically equivalent to the symmetry property of metric spaces.
  2. Identity of congruence: (∀x.(∀y.(∀z.(C(xyzz) ⇒ (xy))))), which is logically equivalent to another metric property.
  3. Transitivity of congruence: (∀u.(∀v.(∀w.(∀x.(∀y.(∀z.(C(uvwx) ⇒ (C(uvyz) ⇒ C(wxyz))))))))), which (together with reflexivity of congruence) implies that congruence of line segments is an equivalence relation.
  4. Identity of betweenness: (∀x.(∀y.(B(xyx) ⇒ (xy)))), which means that if a point lies on a degenerate line segment with equal endpoints, then it is the endpoints.
  5. Pasch’s axiom: (∀u.(∀v.(∀x.(∀y.(∀z.(B(xuz) ⇒ (B(yvz) ⇒ ((∀w.(B(uw, y) ⇒ (B(v, w, x) ⇒ ⊥))) ⇒ ⊥)))))))), which means that any two internal cevians intersect at a point.
  6. Existence of triangles: ((∀x.(∀y.(∀z.((((B(xyz) ⇒ ⊥) ⇒ B(yzx)) ⇒ ⊥) ⇒ B(zxy))))) ⇒ ⊥), which forces the geometry to be non-empty and at least two-dimensional.
  7. Continuity: for any formulae φ(x) and ψ(y), each with only one free variable, we have the axiom (∀w.((∀x.(∀y.(φ(x) ⇒ (ψ(y) ⇒ B(wxy))))) ⇒ ((∀z.((∀x.(∀y.(φ(x) ⇒ (ψ(y) ⇒ B(xzy))))) ⇒ ⊥)) ⇒ ⊥))), which means that we can construct a point given by a Dedekind cut whose sets are definable subsets of a ray.
  8. Five segment: (∀u.(∀x.(∀y.(∀z.(∀u.(∀x’.(∀y’.(∀z’.(((xy) ⇒ ⊥) ⇒ (B(xyz) ⇒ (B(x‘, y‘, z‘) ⇒ (C(yxy‘, x‘) ⇒ (C(yzy‘, z‘) ⇒ (C(uxu‘, x‘) ⇒ (C(u, yu‘, y‘) ⇒ C(uzu‘, z‘)))))))))))))))), which means that a triangle with an extended edge is rigid.
  9. Segment construction: (∀u.(∀v.(∀x.(∀y.((∀z.(B(xyz) ⇒ (C(yzuv) ⇒ ⊥))) ⇒ ⊥))))), which means that we can construct the other endpoint of a segment with a specified endpoint, length and direction.
  10. Euclid’s axiom: To forbid hyperbolic geometry, introduce the axiom (∀u.(∀v.(∀x.(∀y.(∀z.(((xu) ⇒ ⊥) ⇒ (B(xuv) ⇒ (B(yuz) ⇒ ((∀a.(∀b.(B(xya) ⇒ (B(avb) ⇒ (B(bzx) ⇒ ⊥))))) ⇒ ⊥))))))))), which is equivalent to the parallel postulate.
  11. All points are coplanar: To forbid higher-dimensional geometry, introduce the axiom (∀u.(∀v.(∀x.(∀y.(∀z.(((uv) ⇒ ⊥) ⇒ (C(ux, vx) ⇒ (C(uy, vy) ⇒ (C(uz, vz) ⇒ ((B(zxy) ⇒ ⊥) ⇒ ((B(yzx) ⇒ ⊥) ⇒ B(xyz)))))))))))), which means that the perpendicular bisector of two given distinct points is a line.

Rules of inference

A theorem is a formula that is provably true. In order to assign truth to formulae, we are allowed the following rules of inference:

  1. Every axiom is automatically a theorem.
  2. Modus ponens: If P and (P ⇒ Q) are theorems, then so is Q.
  3. Generalisation: If P is a theorem, and x is a variable, then (∀x.P) is also a theorem.

Armed with these axioms and rules of inference, we can prove many theorems in geometry. It is a remarkable fact (known as completeness), first established by Alfred Tarski, that if P is a sentence then either P is a theorem or its negation (P ⇒ ⊥) is a theorem. This is really awesome, since it leads to the following corollary:

Decidability of geometry: We can decide whether a sentence in geometry is true or false, simply by exhaustively proving things until we establish either the sentence or its negation as a theorem.

The theory of algebraically-closed fields of characteristic 0 is also decidable (Lefschetz principle), as is the first-order theory of the reals (also proved by Tarski, and used as a lemma in proving that geometry is decidable). Peano arithmetic is undecidable, a fact known as Gödel’s Incompleteness Theorem.

We are now ready to prove things using this system. Here’s a simple problem:

Exercise 1 (triangle inequality): Prove (∀a.(∀b.(∀x.(∀y.(∀z.(C(xzxa) ⇒ (C(yzyb) ⇒ (B(xya) ⇒ (B(xyb) ⇒ B(xab)))))))))) using the Tarski axioms together with the rules of inference.

If you found that too easy, here’s a slightly more challenging one:

Exercise 2 (question 6, IMO 2011): Prove (∀a.(∀b.(∀c.(∀d.(∀a‘.(∀b‘.(∀c‘.(∀o‘.(∀o.(∀p.(∀q.(∀r.(∀s.(∀t.(∀u.(∀v.(C(o, a, o, b) ⇒ (C(o, b, o, c) ⇒ (C(o, c, o, d) ⇒ (C(oddp) ⇒ (B(odp) ⇒ (C(qaoa) ⇒ (C(rapa) ⇒ (C(qa‘, ra‘) ⇒ (C(qbob) ⇒ (C(rbpb) ⇒ (C(qb‘, rb‘) ⇒ (C(sbob) ⇒ (C(tbpb) ⇒ (C(sb’tb’) ⇒ (C(scoc) ⇒ (C(tcpc) ⇒ (C(s, ctc) ⇒ (C(ucoc) ⇒ (C(vcpc) ⇒ (C(uc’vc’) ⇒ (C(uaoa) ⇒ (C(vapa) ⇒ (C(uava) ⇒ (((q = o) ⇒ ⊥) ⇒ (((r = p) ⇒ ⊥) ⇒ (((s = o) ⇒ ⊥) ⇒ (((t = p) ⇒ ⊥) ⇒ (((uo) ⇒ ⊥) ⇒ (((v = p) ⇒ ⊥) ⇒ (C(o‘, a‘, o‘, b‘) ⇒ (C(o‘, c‘, o‘, b‘) ⇒ ((∀z.(C(ozoa) ⇒ (C(o‘, zo‘, a‘) ⇒ ((((B(oo‘, z) ⇒ ⊥) ⇒ B(o‘, zo)) ⇒ ⊥) ⇒ B(zoo‘))))) ⇒ ⊥)))))))))))))))))))))))))))))))))))))))))))))))) using the Tarski axioms together with the rules of inference.


Posted in Uncategorized | 9 Comments

I’m still alive

So, there hasn’t been a cp4space post for over a fortnight now. I’ll now attempt to excuse this massive lapse, and hopefully convince you that what I’ve been doing in the meantime is still somewhat worthwhile. Amongst other things, I met the world-famous model theorist Ehud Hrushovski completely by coincidence in a random pub in Edinburgh.

Obviously, I’ve been working full-time, and being human it is also necessary to sleep. The evenings are primarily occupied by social events of some nature, which only really leaves the weekends to conduct any projects. So, in reverse chronological order, here is what I’ve been investigating in the last two weekends:

Last weekend: <s, t : s^10 = t^3 = (st)^2 = 1>

This is a surprisingly exciting group.

Firstly, it is straightforward to verify from its presentation that the group is a hyperbolic Dyck group, i.e. the orientation-preserving symmetries of the kaleidoscopic tiling of the hyperbolic plane by triangles with interior angles (π/2, π/3, π/10).

In other words, it is the group generated by the following Möbius transformations:

  • s(z) = z exp(i pi/5);
  • any t with the property that t(t(t(z))) = s(t(s(t(z)))) = z for all z.

Now, this is a ring-theoretic definition, so we can apply a ring automorphism and replace exp(pi/5) with exp(3pi/5) in the above definition without changing the resulting abstract group. However, this is entirely different from a topological perspective, since we have a group of spherical symmetries — rotations — rather than hyperbolic symmetries.

So we can regard this as a dense subgroup of SO(3) generated by two rotations. It transpires that these are precisely the actions on the Bloch sphere by braiding three Fibonacci anyons — weird quasiparticles which can only exist in two dimensions. The element s corresponds to interchanging two strands by a twist whilst leaving the third in situ; the element t corresponds to cyclically permuting the three strands.

Interestingly, this behaviour could be used to build a fault-tolerant topological quantum computer; I’m currently writing an essay on the subject at the moment. See arXiv article 0902.3275 for a description of Fibonacci anyons, and 0707.1889 for a general review of topological quantum computation. It is important that the subgroup of SO(3) is dense, since this means any single-qubit unitary gate can be emulated to arbitrary accuracy by braiding anyons.

The resulting quantum computer, if realisable, would be so beautiful — all computations are performed simply by twisting particles around each other on the plane. Rather like a two-dimensional abacus, but so much more exciting!

Returning to the group, observe it has an index-6 normal subgroup. Specifically, we have a homomorphism into the symmetric group S3, by either considering the action of the braid group on the three strands, or of the hyperbolic group on the colours {red, blue, yellow} in the diagram above. I suspect that this subgroup is simple, since there doesn’t seem to be any obvious normal subgroup. A way to verify this would be to show that given a non-trivial group element, its conjugacy class generates the entire group.

Penultimate weekend: half-baked knightships

For several months, Dave Greene, Chris Cain and Ivan Fomichev have been collaborating on building a variable-speed oblique spaceship in Conway’s Game of Life. After all of the components had been discovered, however, I had no qualms about spending a day writing an object-oriented Python script to assemble the components in an epic display of corollary-sniping!

The pattern file can be obtained from Golly’s online pattern archive. More information is on the ConwayLife wiki page, which seems to give me far more credit than I deserve (not that I’m complaining!). Chris Cain later optimised the design, reducing the period by an entire order of magnitude.

Anyway, as mentioned at the start of the article, it is vitally important that I sleep. Failure to do so could lead to fatigue-induced errors appearing in telecommunications software serving millions of people…

Posted in Uncategorized | 3 Comments