Project 1: Cayley Tables

Due: Friday, February 14, 2020, by 11:59pm


A group is a set equipped with a binary operator that satisfies the group axioms. An example of a group is the set of integers with the addition operation. It is a group because it satisfies the following group axioms.

  1. Closure: a set is closed under a binary operator if applying the binary operator to any two elements in the set produces an element that belongs to the set. The set of integers is closed under addition because adding two integers always results in an integer.
  2. Associativity: a binary operator is associative over as set if the order in which it is applied to any there elements of the set doesn't affect the result. the addition operation is associative because the order of adding three numbers doesn't matter i.e.
    x+(y+z) = (x+y)+z.
  3. Identity: an identity element is an element that can be applied to every element in the set without changing the element. The number 0 is the identity element for addition.
  4. Invertibility: an element x is invertible if there is some element y in the set such that, when x is applied to y we get the identity element e i.e. xy = yx = e. All integers are invertible. The inverse of an integer is its negation. This follows since
    x+(-x) = (-x) + x = 0 for all integers x.

A finite group is a group with a finite set. An example of a finite group is the set {0,1,2} together with addition modulus 3. A cayley table is a convenient way of representing a finite group. It is a table with rows and columns indexed by the elements of the group. Given a group elements a, b and its binary operator *, the content of the cell indexed by row a and column b is the group element a*b. It's like a multiplication table, except that the binary operation is not necessarily multiplication.

The following is a cayley table for the group of integers mod 3.

 |0|1|2|
--------
0|0|1|2|
--------
1|1|2|0|
--------
2|2|0|1|
--------

A cayley table captures all the information of a Group. Given a table we can verify whether it is a Cayley table or not. We only need to verify it satisfies the four group axioms.

Write a C++ program that reads a table, then determines whether it is a cayley table or not. Assume the input is a number n, followed sequence of space separated characters in the set {0, ..., 9, a, ..., z}. Assume the input is always properly formatted and that 0 < n < 36. The characters that follow n are the rows of the cayley table, also assume the n numbers in the first row are distinct (These are the elements of the group). An input of this form encodes a cayley table whose rows and columns are indexed by the fist row of the table. The following is an example.

Consider the following input

3
0 1 2
1 2 0
2 0 1

It encodes the following table.

 |0|1|2|
--------
0|0|1|2|
--------
1|1|2|0|
--------
2|2|0|1|
--------

Notice that the rows and columns are indexed by the first row (0,1, and 2) in the order they appear in the input.

If we rearranged the first row as in the following input then we get a different table.

3
2 1 0
1 2 0
2 0 1

It encodes the following table.

 |2|1|0|
--------
2|2|1|0|
--------
1|1|2|0|
--------
0|2|0|1|
--------

Program Behavior

Suppose you have the following input in a file Test.txt.

3
0 1 2
1 2 0
2 0 1

If your executable is called run, then the command ./run < Test.txt Should produce the following output.

Printing the table.

 |0|1|2|
--------
0|0|1|2|
--------
1|1|2|0|
--------
2|2|0|1|
--------

It is a cayley table! The identity element is 0.

The following input file would produce the following output.

3
0 2 1
1 2 0
2 0 1

Output:

Printing the table.

 |0|2|1|
--------
0|0|2|1|
--------
2|1|2|0|
--------
1|2|0|1|
--------

It is not a Cayley table!
Not associative: (20)0 != 2(00).

In this case we see that the input isn't a cayley table since the operator isn't associative. Since the elements of our groups are limited to single characters, we can denote the group operation by juxtaposition without any ambiguity i.e. we use xy instead of x * y.

In general, you program should behave as follows. It should first print the cayley table, then test to see if the table satisfies all the group axioms. It should test them in the order: closure, associativity, identity, then inverse.
If the table fails any of these tests it should print a message saying that the table isn't a Cayley table. Then it should do ONE of the following.

If the table doesn't satisfy closure, it should also print out an element that shouldn't be in that table. Then it should terminate.

Otherwise, if the table doesn't satisfy associativity, it should print elements x,y,z such that (xy)z isn't equal to x(yz). As shown in the previous example. Then it should terminate.

Otherwise, if the table doesn't satisfy identity, it should print out that the table has no identity element. Then it should terminate.

Otherwise, if the table doesn't satisfy inverse, it should print an element without an inverse. Then it should terminate.

Program Structure

Your program should consist of the files: cayley.cc, cayley.h, driver.cc, Makefile.

cayley.cc: this file MUST include the following functions with the signature specified.

void read_table(char table[MAX][MAX], int table_size):
This function reads the table. It reads in (where n = table_size) numbers into the array table. These are the n rows of the table.

void print_table(char table[MAX][MAX], int table_size):
This function prints table as a cayley table of size table_size. It should be printed as presented in the examples above. It should have row and column boundaries.

bool is_closed(char table[MAX][MAX], int table_size, char& outlier):
This function is meant to verify the closure axiom. It should return true if and only if the table stored in table is closed i.e. every operation gives an element in the group. If the group isn't closed, then outlier should be set to a character in the table that doesn't belong. MAX is a constant integer that is set to 36 (the number of allowed characters). It should be declared in cayley.h.

void is_associative(char table[MAX][MAX], int table_size, char& x, char& y, char& z, bool& ans).
This function is meant to verify the associativity axiom. It should set ans to true if and only if the table's operation is associative. If it isn't it should set x, y, and z to elements that violate associativity. They should be set such that (xy)z != x(yz).

void has_identity(char table[MAX][MAX], int table_size, char& identity):
This function is meant to verify the identity element axiom. It should set identity to the integer constant ERROR (Should be declared in cayley.h and set to -1) if the table has no identity element. Otherwise, identity is set to an identity element in the table.

void all_have_inverse(char table[MAX][MAX], int table_size, char& ans)
This function is meant to verify the inverse element axiom. It should set ans to the integer constant GOOD (Should be declared in cayley.h and set to -2.) if every element in the group has an inverse. Otherwise, out out should be set to an element in the table without an inverse.

These functions are required, you'll lose a lot of point if they aren't implement as I have specified. They should also be implemented in the order they are presented above. Don't make your functions over complicated, make helper functions to simplify your code. All helper functions should be implemented in cayley.cc.

cayley.h: this file should contain the header/signature of all functions in cayley.cc. It should also include the constants ERROR (set to -1) and GOOD (set to -2). All your functions should have appropriate pre/post comments. You can omit pre/post comments in cayley.cc but they must be included in cayley.h.

driver.cc: this file should have the main function. The main function should read in the table, print it, then indicate whether the table is a cayley table or not.

Makefile: the make file should create an executable called run. In a folder with all your files, the make command should produce the executable run. It should be properly designed so that it always produces an up to date executable.

Submission

This project is due on Friday the 14th at 11:59:59 PM. The files driver.cc, cayley.cc, cayley.h, Makefile, Test1.txt, Test2.txt, TestCases.txt (ONLY) should be placed in a folder named with your last name only. Compress the folder using zip and upload it to Inquire. Test1.txt and Test2.txt are two test cases for you program. TestCases.txt is an explanation of each test case and the expected output of your program.

Grading

Correctness: 60%
Test cases: 10%
Style: 10% (code alignment, comments, not using magic numbers, ...)
Makefile: 10%
Following submission guide lines: 10%