Java Model of Basic Algebraic Structures Petr Grillinger * pgrillin@kiv.zcu.cz Jaroslav Kačer * jkacer@kiv.zcu.cz Abstract This article presents a model of basic algebraic structures implemented in Java. The model is highly portable and extensible, and contains strong self-checking mechanisms. It is based on finite sets and provides brute-force methods simulating basic operations on algebraic structures. The implemented structures (from set to ring) form a single-rooted hierarchy of classes (the root is a set element). So far the model is not very useful for automated theorem proving, because is lacks support for intentional set definitions, but this should change in the future. 1. Introduction Many solutions to programming problems are based on principles from algebra most constructs that are used can be described by appropriate algebraic structures. Some of these structures are directly represented (e.g. sets, vectors, functions) others are provided in a less obvious way (e.g. additive group of whole numbers). Conversely, by using a programming language we can build an explicit model of these algebraic structures. Such model could be used as an alternative means of writing algebraic expressions. It would also enable the automation of some basic algebraic tasks verification of specified axioms by brute force approach. This work aims to create a basic set of algebraic structures that could be used to quickly solve simple algebraic tasks. The model must be well designed and open to allow further extensions. We aim for portability, clarity of design and robustness, while performance is of low importance. Many algebraic structures form a natural hierarchy (e.g. set monoid group) that can be easily represented by object oriented modeling. We chose to implement the model in Java, because from the wide range of OO languages, Java provides the best portability. Moreover, the strong type-checking and mandatory exception handling makes Java a very safe language. 2. Model Limitations Only a small subset from the large number of various algebraic structures was selected for implementation. This subset can be seen in a tree form (the branches indicate parent-descendant relationship between classes) in Fig.1. Common programming methods cannot represent infinite sets and it is in no way possible to successfully perform a brute force algorithm on such sets. For this reason, we are not going to include infinite sets and problems that require them will have to use an adequate substitute representation (e.g. randomly chosen finite subset). This limitation makes the model only partially useful for automated theorem proving (results for infinite sets will be probabilistic), but simplifies significantly the implementation. * Ing., University of West Bohemia, Department of Computer Science and Engineering, Univerzitní 22, Plzeň 30614, Czech Republic
Element Function Set Vector Relation Operation Monoid CartesianProduct Group Ring Fig. 1: Class specialization tree (parent descendant) 3. Basic Classes The model is encapsulated in a Java package labeled cz.zcu.fav.kma.alg. It contains all classes representing individual algebraic structures as well as several support classes. We will describe in some detail the basic structures (all that are depicted in Fig. 1), the others are only listed. 3.1. Class Element Element is an abstract class that defines any single element of a set or a vector. Every element is specified by its type (instance of class ElementType) and value. The type is used to identify a group of elements with common properties, e.g. integers. Only elements of the same type can be in one set and many operations require specific element types. The value of an element is used for comparison and two elements are identical if they have the same type and value. The method getidentification() is used to retrieve the textual value of an element. 3.2. Class ElementType An element type is defined by a string constant (e.g. INTEGER ). This constant is used during the creation of a new type to determine whether a type with the same string already exists (then the existing type is used) or not (a new type is created). To allow this behavior, the class is constructed as a factory, i.e. instances are obtained by calling the method createtype() rather than by using a constructor. 3.3. Class Set This class is a container that manages instances of the Element class. The elements are not ordered, must have the same type, and no two elements may be equal. As mentioned previously, infinite sets are not supported this means that every set can be defined by a simple enumeration of its elements (extensive set). The extensive definition allows to easily iterate through elements (the standard Java Iterator is supported). A set is not fully defined until the type of its elements is known the element type is fixed permanently after the first element is inserted. The type of a set is defined as SET(ELEMENT_T).
3.4. Class Vector A vector is used to hold a fixed number of elements in given order. The elements must have the same type, and duplicates are possible. The number of elements must be specified during creation and the element type (used for the vector type and identification) is collected as the first element is inserted. A vector is not fully defined until the type of its elements is known the element type is fixed permanently after the first element is inserted. The type of a vector is defined as VECTOR[#](ELEMENT_T). 3.5. Class Function This is an abstract class that defines the basic properties of any function. Descendants should override methods getvalue() and gettransformationdescription() the later is used to automatically create the identification of the function (function is also an element and this is its visible value). The constructor of this class requires two parameters domain and codomain both are used to construct a complete element type for the function. The type of a function is defined as FUNCTION(DOMAIN_T,CODOMAIN_T). 3.6. Class Relation A relation is a subset of the Cartesian product of several sets. It can be expressed also as a function with codomain {0,1 that returns the integral number 1 if the elements in a given vector meet the relation, 0 otherwise. In this implementation, Relation is descended from the Function class and its codomain is fixed. It does not override the abstract methods of function, so it remains an abstract class. The type of relation depends on the domain, i.e. its textual description is RELATION(DOMAIN_T). 3.7. Class Operation Operation is a function where domain is the same as codomain or a Cartesian product on codomain. This means, that operation is descended from Function, and only the codomain and the dimension of domain are specified (number of operands). The operation type depends on the number of operands and codomain type, i.e. the textual form is OPERATION[#](CODOMAIN_T). 3.8. Class CartesianProduct A Cartesian product is a set of all vectors that can be produces by combining elements of given sets in defined order. The memory consumption of this product can be considerable, so the current implementation is intentional and not extensive. This should be changed in the future or the class should provide an iterator for sequential browsing. The type is a set in fact and is defined by the sets forming the product. These sets are given in a vector of fixed size, so the textual type definition is SET(VECTOR_T) 3.9. Class Monoid Monoid groups a set of elements, a binary operation on this set and an identity element into a single unit. All three parts must be specified on construction, but only the type of the set elements defines the type of the monoid. The correctness of a monoid is checked in a simple way during creation and a thorough check that verifies all axioms can be requested explicitly. The textual type description is MONOID(ELEMENT_T). 3.10. Class Group A group extends the monoid structure by an inverse operation an instance of UnaryOperation class. All rules from monoid are still valid, the correctness check is extended to verify the inverse operation. The textual definition of type is GROUP(ELEMENT_T).
3.11. Class Ring Similarly as group is an extension of monoid, ring is an extension of group. It adds a second binary operation with an identity element and places another restriction on the first operation it must be commutative. Moreover, the first operation must be distributive with respect to the second. The textual type definition is RING(ELEMENT_T). 3.12. Other Classes The so far described classes represent the most important keys of the algebraic model. Other classes are present and often more usable because they provide particular services and not abstract interfaces. These classes are only listed in the following paragraph and more detailed description can be easily found in program-generated documentation (available at http://www.kiv.zcu.cz/~jkacer). AdditionModulo BinaryOperation BinaryRelation CharacteristicFunction EmptySet EquivalenceClass IdentityFunction Insertion IntegralNumber InverseAdditionModulo MultiplicationModulo NestedFunction OrderedPair Permutation PermutationSet RelationOnSet ResidueClass UnaryOperation 3.13. Singletons Some classes serve special purpose and only one instance of such class is created. These classes were implemented with a hidden constructor (private) and the actual instance can be accessed through method getinstance() only. So far only two classes are singletons: EmptySet Set01 4. Self-Checking Mechanisms The model contains several independent checking mechanisms that are used for different purposes. 3.1. Class Tests A class test is written by the designer of the class to verify that the implementation is correct. It typically inherits the class test from its parent and then executes a test suite for the new features. The test suite should contain the creation of several instances and verification of every new method. It is generally not possible to determine correctness automatically it is up to the user to visually check the output of the class test. The test can be run from the command line by typing this sequence: java cz.zcu.fav.kma.alg.<class_name> 3.2. Instance Test This kind of test can be started during program execution by calling the method selftest() of any class descended from Element. The method will verify that the definition of the instance is complete (for non-atomically initialized classes) and that all axioms for the given algebraic structure are fulfilled. E.g., any function must have a domain, a codomain, and a transformation rule that handles any element from domain and produces only elements from codomain. The instance test returns true if all tests are passed, false otherwise.
3.3. Exception System The model enforces strong error checking by using a hierarchy of exceptions. All exceptions that denote the violation of algebraic rules are descended from a single class AlgException. Java guarantees that an exception must be handled or correctly declared in the interface, so user applications are verified for robustness already during compilation. 5. Example A simple example was prepared to demonstrate the basic features of the model. The example solves the following problem: Find all automorphisms of an additive group Z 8 (elements are residues from modulo 8). An automorphism is a bijective function f on a group that preserves the structure of the group, i.e. for every two elements x, y and group operation + it is true: f(x+y) = f(x)+f(y). From the function definition follows, that an automorphism is always a permutation on the group, so the fastest approach to the task is to generate every permutation (use the class PermutationSet) and test if the additive operation is preserved. The group can be easily constructed from a ResidueClass set, the binary operation AdditionModulo, and unary operation InverseAdditionModulo. The test whether a function is automorphism or not is already included in the Function class. public class Example2 { public static main(string[] args) { Group g8 = new Group( new ResidueClass(8), new AdditionModulo(8), new IntegralNumber(0), new InverseAdditionModulo(8)); Set all_perm = new PermutationSet(g8.getSet()); Iterator iter = all_perm.iterator(); Function f; while (iter.hasnext()) { f = (Function) iter.next(); if (f.isautomorphism(g8)) System.out.println(f.getIdentification() + " is automorphism."); 6. Conclusions The described model of algebraic structures has so far quite limited capabilities, but provides a stable and easily extensible interface. The Java language provides excellent portability and applications robustness. The example in previous section demonstrates that solving a seemingly complicated task can be quite easy given that the necessary tools are available. The most severe limitations of the model are the incomplete implementation of some structures (e.g., testing of sub-groups, finding the kernel) and the missing structures (e.g. fundamental group, intentional sets). This flaw will be continuously removed in the future. Bibliography [1] S. Mac Lane, G. Birkhoff, 1968: Algebra (2 nd edition), The Macmillan Company, New York. Slovak translation. [2] B. Eckel, 2002: Thinking in Java (3 rd edition), Prentice-Hall. ISBN 0131002872. Online version at http://www.mindview.net/books/tij.