--- /dev/null
+package org.simantics.scl.compiler.parser.generator.compression;
+
+import java.util.Arrays;
+
+import org.simantics.scl.compiler.parser.generator.table.ParseTableBuilder;
+
+public class GCCompress {
+
+ public static final int DONT_CARE = ParseTableBuilder.ERROR_ACTION;
+
+ private static int[][] compressRows(int[] colors, final int[][] table) {
+ final int columns = table[0].length;
+ int colorCount = GraphColoring.color(colors, new GraphColoring.ColGraph() {
+ @Override
+ public int size() {
+ return table.length;
+ }
+
+ @Override
+ public boolean areConnected(int a, int b) {
+ int[] aRow = table[a];
+ int[] bRow = table[b];
+ for(int i=0;i<columns;++i) {
+ int aV = aRow[i];
+ int bV = bRow[i];
+ if(aV != DONT_CARE && bV != DONT_CARE && aV != bV)
+ return true;
+ }
+ return false;
+ }
+ });
+
+ final int[][] compr = new int[colorCount][columns];
+ for(int i=0;i<compr.length;++i)
+ Arrays.fill(compr[i], DONT_CARE);
+
+ for(int i=0;i<table.length;++i) {
+ int color = colors[i];
+ int[] inRow = table[i];
+ int[] outRow = compr[color];
+ for(int j=0;j<columns;++j) {
+ int v = inRow[j];
+ if(v != DONT_CARE)
+ outRow[j] = v;
+ }
+ }
+
+ return compr;
+ }
+
+ private static int[][] compressColumns(int[] colors, final int[][] table) {
+ final int columns = table[0].length;
+ int colorCount = GraphColoring.color(colors, new GraphColoring.ColGraph() {
+ @Override
+ public int size() {
+ return columns;
+ }
+
+ @Override
+ public boolean areConnected(int a, int b) {
+ for(int i=0;i<table.length;++i) {
+ int[] row = table[i];
+ int aV = row[a];
+ int bV = row[b];
+ if(aV != DONT_CARE && bV != DONT_CARE && aV != bV)
+ return true;
+ }
+ return false;
+ }
+ });
+
+ final int[][] compr = new int[table.length][colorCount];
+ for(int i=0;i<compr.length;++i) {
+ Arrays.fill(compr[i], DONT_CARE);
+ }
+ for(int i=0;i<table.length;++i) {
+ for(int j=0;j<columns;++j) {
+ int v = table[i][j];
+ if(v != DONT_CARE) {
+ int color = colors[j];
+ compr[i][color] = v;
+ }
+ }
+ }
+
+ return compr;
+ }
+
+ public static CompressedTable compress(int[][] table) {
+ System.out.println("Compress:");
+ System.out.println(" Rows: " + table.length);
+ System.out.println(" Columns: " + table[0].length);
+
+ int[] rowIndex = new int[table.length];
+ int[] columnIndex = new int[table[0].length];
+
+ table = compressRows(rowIndex, table);
+ table = compressColumns(columnIndex, table);
+
+ System.out.println(" Compressed rows: " + table.length);
+ System.out.println(" Compressed columns: " + table[0].length);
+
+ int columns = table[0].length;
+
+ int[] compressedTable = new int[table.length * columns];
+ for(int i=0;i<table.length;++i)
+ System.arraycopy(table[i], 0, compressedTable, i*columns, columns);
+ for(int i=0;i<rowIndex.length;++i)
+ rowIndex[i] *= columns;
+ return new CompressedTable(rowIndex, columnIndex, compressedTable);
+
+ //for(int[] row : table)
+ // System.out.println(Arrays.toString(row));
+ }
+
+}