mtmtcl

What
mtmtcl (from mathematical)
Where
From the contact
Description
Collection of implementations in Tcl of various mathematical structures (with a certain preference for algebra) and specifications of interfaces to make them possible to combine
Contact
mailto: Lars(DOT)Hellstrom(AT)residenset(DOT)net

(Why no download, someone may ask. Well, the codebase started out as simple examples in a document primarily aimed at specifying interfaces — kind of "that's the spec of ring, so lets consider an easy example: the integers" — and then grew by bits and pieces, so it's not packaged in any way. It's perfectly docstrip::sourceable, but could do with being reorganised.)

Philosophy

In the standard set-theoretic foundation of mathematics, everything (every number, every pair, every vector, every function, every relation, etc.) is a set of some form. Since every set — no matter how curious a collection of items it may be — is also a valid mathematical object, it follows that every "ordinary" mathematical object has also at least one alternative interpretation. This implies that the meaning of a mathematical object can never be part of the object itself; meaning always derives from the context: from the operations using which one operates on the object in question. For example, a pair of integers is a perfectly natural representation for each and every one of:

  • An element of ℤ×ℤ (Cartesian product of two rings).
  • A Gaussian integer (an element of ℤ+iℤ).
  • A rational number (element of ℚ).
  • An element of ℤ² (inner product module of pairs of integers).
  • An element of some ℤ/n × ℤ/n (pair of integers modulo n).
  • A rational point on some elliptic curve over ℤ/p for p prime.

All of them have a concept of multiplication of two such pairs, but the respective multiplication operations are very different from each other. Yet they are all natural interpretations of "multiplication" — for their particular interpretations of the objects.

This fits well with Tcl's general "duck-typing", where the meaning of a value is always determined by the operation which makes use of it. It is however also an approach which has not been tried much by those who have tried to implement computations with higher mathematical objects. The route most travelled has rather been that of seeking to imitate the mathematical notation, and thus unify all of the above operations as a single (heavily overloaded) *. In order to still provide all of them, these systems then introduce elaborate type systems for mathematical objects, and rely on runtime disambiguation to figure out what the programmer meant. While such constant reinterpretations of programs are probably not good for performance, I find it more worrying that they make it hard to establish correctness, especially when there are several abstraction levels involved; combining modules may lead to "cocktail effects" where an unintended alternative interpretation suddenly appears that causes a given expression to suddenly mean something other than the programmer intended. Acknowledging that the meaning is always in the context removes this source of errors.

In mtmtcl, each structure is associated with an "object command", whose methods are the operations on elements of that structure. Hence the rational number multiplication can be some "ℚ *" command, while the Gaussian integer multiplication can be some "ℤ+iℤ *" command. Rational number addtion can be "ℚ +" and Gaussian integer addition (which would probably be the same as in ℤ×ℤ and ℤ²) can be "ℤ+iℤ +". Well, at least in principle.

While Tcl is certainly Unicode-savvy enough to support ℚ and ℤ+iℤ as command names, whereas we poor Anglified programmers might be more comfortable with names such as Gaussian_integer, the most common form of "structure call" appearing in mtmtcl-code might actually be that of the variable reference: {*}$R, where the R variable stores the underlying structure. In order to compute the R-product or R-sum of two values a and b, one then uses commands such as

  set product [{*}$R * $a $b]
  set sum [{*}$R + $a $b]

This is because it is often just as easy to code a construction that implements some structure on top of some other structure as it is to implement a particular instance of that structure. Thus, rather than implementing Gaussian integers from scratch, one implements a generic "complexification" construction. Applying it to ℤ gives rise to ℤ+iℤ, applying it to ℚ gives rise to ℚ+iℚ, and applying it to ℝ gives rise to ℂ. (In practice, one might not be content with this as there is much about ℂ that has no counterpart for ℤ+iℤ and vice versa, but it is a start by which one can get surprisingly far with very little effort.)

[Also say something about the advantages of value semantics.]

Features

Things currently implemented include:

  • Integers (ring)
  • Integers modulo n (ring)
  • Real numbers as doubles (ring)
  • Free monoid
  • Free abelian monoid (power products)
  • Semigroup algebra
  • Polynomials (obtained as the semigroup algebra of the free abelian monoid, or just the free monoid if one wishes to consider polynomials in noncommuting variables)
  • Free rank n module
  • Various matrix PROPs
  • Export of elements as OpenMath, and further conversion to LaTeX code.