/* Research Project: Graphical Database for Category Theory J. Bradbury, Dr. R. Rosebrugh, I. Rutherford Mount Allison University 2001 File: Category.java Description: This class contains all of the information that is needed for a category and some useful functions */ import java.io.*; public class Category { IniSettings ini; //IniSettings class that contains the lengths //of the arrays in the Category class String name; //Name of the category String[] obj; //Names of the objects in the category int num_objects = 0; //Number of objects in category int[][] arr; //domain and codomain of arrows String[] arrow; //Names of arrows in a category int num_arrows = 0; //Number of arrows in category Relation[] relations; //Contains relations in category int num_relations = 0; //Number of relations in category String comment; //Comments about the category File file_; //Name of file that category was opened, //loaded, or saved in String gml; //Text version of graphical interpretation //of thecategory String originalGml; //Text version of the original graphical //interpretation of the category CategoryModified mod; //This contains all of the information //about modifications to the original //category fill public Category() // default constructor { ini = new IniSettings(); name = new String(); obj = new String[ini.getMAXWORD()]; num_objects = 0; arr = new int[ini.getMAXARR()][2]; arrow = new String[ini.getMAXARR()]; num_arrows = 0; relations = new Relation[ini.getMAXARR()]; num_relations = 0; comment = new String(); gml = "graph [\ndirected 1\n]\n"; originalGml = "graph [\ndirected 1\n]\n"; mod = new CategoryModified(); } public boolean isModified() //Return true if the category was not originally saved //or has been modified since it was last saved { if (mod.functorCat || mod.createCat || mod.dualCat || mod.dataAdded || mod.dataRemoved || /*(!gml.equals(originalGml) && !originalGml.equals("")) || mod.nameChanged ||*/ mod.madeConfluent) return true; else return false; } public void copyCategory(Category c) { if (c == null) return; int i, j, temp; name = new String(c.name); num_objects = c.num_objects; num_arrows = c.num_arrows; num_relations = c.num_relations; for (i=0; i path_len(path2)) { return(true); } else { if ((path_len(path1)) == (path_len(path2))) { if ((path_len(path1) == 1) && (path1[0] == ini.getIdentityCode())) return(false); j = 0; while (j < path_len(path1)) { if (path2[j] > path1[j]) { return(false); } else { if (path2[j] < path1[j]) { return(true); } } j++; } } } return(false); } public Category makeDual() /* Purpose: To dualize a category Design: Makes a dual of the category and returns it */ { char over, leave; int i, j, temp; int temp2[] = new int [ini.getMAXWORD()]; int temp3[] = new int [ini.getMAXWORD()]; boolean done; Category B = new Category(); B.name = name; // + "DUAL"; B.num_objects = num_objects; B.num_arrows = num_arrows; B.num_relations = num_relations; for(i=0;i=0;j--) { temp2[path_len(relations[i].lhs)-1-j] = relations[i].lhs[j]; } temp2[path_len(relations[i].lhs)] = -1; for(j=path_len(relations[i].rhs)-1;j>=0;j--) { temp3[path_len(relations[i].rhs)-1-j] = relations[i].rhs[j]; } temp3[path_len(relations[i].rhs)] = -1; Relation r = new Relation(); if (greater(temp2,temp3)) { r.lhs = copy_path(temp2); r.rhs = copy_path(temp3); } else { r.lhs = copy_path(temp3); r.rhs = copy_path(temp2); } B.relations[i] = r; } return B; } public int all_arr(int obj, int arrows[]) /* Parameters: obj: integer representing an object in the category arrows: array containing all arrows with object obj as their domain Purpose: Returns an integer whose value is the number of arrows in the category with object obj as their domain. The array is passed back containing all such arrows. */ { int j, k=0; for (j=0;j size) size = j; int[] ret = new int[j+1]; for (i=0; i') { head = i-1; tail = i; } if ((arro.charAt(i) == ',') || (arro.charAt(i) == '.')) { if (prev == 0) arrow[num_arrows] = arro.substring(prev, colon); else arrow[num_arrows] = arro.substring(prev+1, colon); String domain = arro.substring(colon+1, head); for (int j = 0; j < num_objects; j++) { if (obj[j].equals(domain)) arr[num_arrows][0] = j; } String codomain = arro.substring(tail+1, i); for (int j = 0; j < num_objects; j++) { if (obj[j].equals(codomain)) arr[num_arrows][1] = j; } num_arrows++; prev = i; } } } } //end of parse arrows //start of parse relations public void parseRelations(String rel) //This method parses a string of relations { int i =0; int prev = 0; int equals = 0; rel = rel.replaceAll(" ", ""); rel = rel.replaceAll("\t", ""); if (rel.charAt(0) != '.') { for (i=0; i < rel.length(); i++) { if ((rel.charAt(i) == ',') || (rel.charAt(i) == '.')) { String relation = rel.substring(prev, i); prev = i+1; relations[num_relations++] = get_rel(relation); // System.out.println(path_to_string(relations[num_relations-1].lhs) + " = " + path_to_string(relations[num_relations-1].rhs)); } } } } public boolean check_oneone(int path[], int domain, int codomain, HomTree gamalbet, int alpha[], int beta[], HomTree gammatree, int maxloop, HomTree pathtree) /* Parameters: path: the current path domain: the current object of the path codomain: the object we are trying to find all arrows to objects: an array of integers which keeps the function from exceeding the maximum number of loops gamalbet: a tree returned with all gamma-alphas and gamma-betas alpha: first projection to the productobj being tested beta: second projection to the productobj being tested gammatree: the tree of all arrows from productobj to codomain maxloop : endomorphism limit Purpose: To generate the reduced hom set from one object to another and check 1-1 Design: Creates a tree gamalbet containing the reduced form of all the gamma-alphas and each gamma-alpha having a subtree which contains all of the gamma-betas paired with it. Also creates a tree gammatree with all the gamma paths */ { int i, j, len, number, codom, endo = 0; int arrow_array[] = new int [num_arrows]; int reducedGammaBeta[] = new int[ini.getMAXWORD()]; int reducedGammaAlpha[] = new int[ini.getMAXWORD()]; path = reduce(path); len = path_len(path); if (path[0] == -2) path[0] = -1; for (i=0; i=0; j--) path[j+1] = path[j]; // add the ith arrow to the path path[0] = arrow_array[i]; // then check all arrows from the object recursively. if (!check_oneone(path, domain, codomain, gamalbet, alpha, beta, gammatree, maxloop, pathtree)) return false; len = path_len(path); for (j=0; j are in our tree. */ { int i, j, len, number, codom, endo = 0; int arrow_array[] = new int[num_arrows]; path = reduce(path); if (path[0] == -2) path[0] = -1; // check to see if we've passed the endomorphism limit len = path_len(path); for (i=0; i 0) for (i=0; i=0; j--) path[j+1] = path[j]; // add the new arrow to the path path[0] = arrow_array[i]; // recursively check all paths; like a depth-first search if (!check_onto(path, domain, codomain, gamalbet, rhotree, maxloop, pathtree)) return false; for (j=0; j<=len; j++) path[j] = path[j+1]; // remove the newest arrow from the path; "pop" it } } } else { //endopassed = true; return false; } return true; } public int makeHomTree(int path[], HomTree homtree, int obj1, int obj2, int maxloop, HomTree pathtree) /* Parameters: path[] - integer array containing the path followed so far objects[] - integer array containing a list of all the objects visited along the path homtree - the tree to contain the paths obj1 and obj2 - check for paths from obj1 to obj2 maxloop - max endomorphism limit Purpose: To generate the reduced hom set from one object to another as a tree Design: Creates a tree homtree of all the reduced paths from one object to another. */ { int i, j; int endo = 0; path = reduce(path); int pathlen = path_len(path); int numpaths = 0; if (path[0] == -2) path[0] = -1; for (i=0; i=0; i--) // all arrows from obj1 { // add the new arrow to the path, and the new object to the object list for (j=path_len(path); j>=0; j--) path[j+1] = path[j]; path[0] = arrows[i]; // recursive check on all paths; like a depth-first search on a graph numpaths += makeHomTree(path, homtree, arr[arrows[i]][1], obj2, maxloop, pathtree); // now remove the arrow and object from the path and object list for (j=0; j<=pathlen; j++) path[j] = path[j+1]; } // if we're at the second object, then add the path to the tree if (obj1 == obj2 && pathlen != 0) { numpaths++; homtree.addPath(newpath); } } } else { //this.setEndoPassed(true); } return numpaths; } public String toString() { return name; } }