import java.util.Vector; import java.util.Stack; import java.util.Enumeration; import java.util.StringTokenizer; class Chu implements Conformable { /* A Chu space is a matrix with entries drawn from * a set of some finite size K. The members of the * set are represented by numbers in [0,K-1]. */ private int K; private int nrows; private int ncols; private int matrix[][]; private Chu standard; // Pointer to standardized version of this space /* Trusting constructor: performs no consistency checks */ private Chu(int K, int nrows, int ncols, int matrix[][], boolean standardized) { this.K = K; this.nrows = nrows; this.ncols = ncols; this.matrix = matrix; standard = (standardized ? this : null); } /* Special constructor: builds tensor unit */ Chu(int size) { this(size, 1, size, new int[1][size], true); for(int i=0;i10) throw new ParseException("K="+K+" is out of bounds. Use 0<=k<=10"); else kInit = true; } catch(NumberFormatException x) { if(kText.length() != 0) throw new ParseException("can't parse K='"+kText+"'"); } } boolean nrowsInit=false; nrows = 0; if (rowText!=null) { rowText = rowText.trim(); try { nrows = Integer.parseInt(rowText); if(nrows<0) throw new ParseException("#rows="+nrows+" is out of bounds. "+ " Use nrows>=0"); else nrowsInit = true; } catch(NumberFormatException x) { if(rowText.length() != 0) throw new ParseException("can't parse #rows='"+rowText+"'"); } } boolean ncolsInit=false; ncols = 0; if (colText!=null) { colText = colText.trim(); try { ncols = Integer.parseInt(colText); if(ncols<0) throw new ParseException("#cols="+ncols+" is out of bounds. "+ " Use ncols>=0"); else ncolsInit = true; } catch(NumberFormatException x) { if(colText.length() != 0) throw new ParseException("can't parse #cols='"+colText+"'"); } } // Set up rowTokenizer // Infer nrows if not already initialized // Set up matrix if (text==null) text = ""; text = text.trim(); // cut trailing whitespace, esp. newlines StringTokenizer rowTokenizer = new StringTokenizer(text,"\n"); if(!nrowsInit) { nrows = rowTokenizer.countTokens(); nrowsInit = true; } matrix = new int[nrows][]; // Build rows from rowTokenizer: store results in matrix int r; for(r=0; r K-1="+(K-1)); } } else { // !kInit entries.addElement(new Integer(d)); if(d>=K) K=d+1; } } else { // !isDigit int c = entries.size(); throw new ParseException("Entry ("+(r+1)+","+(c+1)+")"+ "=`"+rowString.substring(c,c+1)+ "' is not a digit"); } } // Infer ncols if not already initialized // Set up matrix[r] if(!ncolsInit) { ncols = entries.size(); ncolsInit = true; } matrix[r] = new int[ncols]; // copy ncols elements into matrix[r]: pad as needed int c; for(c=0 ; c10) throw new ParseException("K="+K+" is out of bounds"); StringBuffer out = new StringBuffer(100 + nrows*(ncols+1)); for(int r=0;r K) K = B.K; int nrows = A.nrows + B.nrows; int ncols = A.ncols + B.ncols; int matrix[][] = new int[nrows][ncols]; for(int r=0;r K) K=B.K; int nrows = A.nrows * B.nrows; int ncols = A.ncols + B.ncols; int matrix[][] = new int[nrows][ncols]; int r=0; int c=0; for(int ar=0;ar K) K=B.K; // Classify columns of A and B int[] classificationA = A.classifyCols(); int[] classificationB = B.classifyCols(); // Count rows and columns of answer. // A column of the answer consists of the concatination of // a column of A and a column of B. Duplicates are not allowed. // The column (state) of A must be final (= FINAL || UNKNOWN). // The column (state) of B must be initial (= INITIAL || UNKNOWN). int nrows = A.nrows + B.nrows; int ncols = 0; for(int ac=0; ac nothing private static final int INITIAL = 1; // < something,> nothing private static final int FINAL = 2; // < nothing,> something private static final int MIDDLE = 3; // < something,> something private static final int DUPLICATE = 4; // == previous something // classifyCols: Returns an array of integers which classify // the columns of a Chu space into the five catagories above. private int[] classifyCols() { int classification[] = new int[ncols]; OUTER: for(int c=0; c col d, so nothing can be infered case IC: continue INNER; // col c == col d, throw out c by classifying it as DUPLICATE. case EQ: classification[c] = DUPLICATE; continue OUTER; // col c < col d. case LT: switch(classification[c]) { case UNKNOWN: classification[c] = INITIAL; break; case FINAL: classification[c] = MIDDLE; break; } switch(classification[d]) { case UNKNOWN: classification[d] = FINAL; break; case INITIAL: classification[d] = MIDDLE; break; } break; // col c> col d. case GT: switch(classification[c]) { case UNKNOWN: classification[c] = FINAL; break; case INITIAL: classification[c] = MIDDLE; break; } switch(classification[d]) { case UNKNOWN: classification[d] = INITIAL; break; case FINAL: classification[d] = MIDDLE; break; } break; } } // INNER } // OUTER return classification; } private static final int EQ = 0; // == private static final int LT = 1; // < private static final int GT = 2; //> private static final int IC = 3; // aka incomparable // compareCols: Compares two columns componentwise // and returns one of the four code values above. private int compareCols(int col1, int col2) { int result = EQ; for(int r=0; r B.K) K = B.K; // The "rows" of implication are Chu transforms from A to B // These transforms consist of matrices that are ambigiously // composed of columns of A or rows of B. Thus the size of // these rows/transforms/matrices is: int size = A.nrows*B.ncols; // The number of transforms is not known in advance, so // for now they will go in a variable-length Vector: Vector transforms = new Vector(); // Build the MatrixGenerator, using prefix trees // of the possible rows and columns of the matrix: MatrixGenerator MG = new MatrixGenerator(B.rowTree(), A.colTree()); while (MG.next()) { // Count instances of this matrix. // Whenever there are multiple choices for a row or column, // the number of instances is multiplied. int num_instances = 1; for(int r=0;r matrix[r][c]) h=m; else l=m+1; continue search; } // end compare /* If we get here, we have a match. * Throw out row r */ continue sort; } // end search /* We have a new row. Insert it! */ for(int i=num_unique;i>l;i--) unique_rows[i] = unique_rows[i-1]; unique_rows[l] = r; num_unique++; } // end sort return num_unique; } private int col_sort(int[] unique_cols) { /* Record (in unique_cols) and count (in num_unique) all unique cols. * Throw out all copies. */ int num_unique = 0; sort: for(int c=0;c matrix[r][c]) h=m; else l=m+1; continue search; } // end compare /* If we get here, we have a match. * Throw out col c */ continue sort; } // end search /* We have a new col. Insert it! */ for(int i=num_unique;i>l;i--) unique_cols[i] = unique_cols[i-1]; unique_cols[l] = c; num_unique++; } // end sort return num_unique; } public static void main(String args[]) { try { Chu[] chus = new Chu[2]; chus[0] = new Chu(null, null, null, "1100\n1010"); chus[1] = new Chu(null, null, null, "000111222\n012012012\n"); for(int i=0; i

AltStyle によって変換されたページ (->オリジナル) /