/** * Code originally by Ahmed Abdel Mohsen * Code modified by Daniel Rinehart * Original version at https://www.ccs.neu.edu/course/csg260/ssl/RelationReduction/ */ /** * Utility class used to work with relation clauses that are of rank three and * represent truth tables between 0 and 255. */ class Relation1 { /** * Private constructor to force utility class usage. */ private Relation1() { } /** * Reduce the relation by setting the variable in the location specified by * variableNumber to value. * * @param relationNumber * Current relation number * @param variableNumber * Variable number to set * @param value * Value to set variable to * @return Reduced relation number */ public static int reduce(int relationNumber, int variableNumber, int value) { int r, m; // new relation number m = getMagicNumber(variableNumber, value); r = (relationNumber & m); if (value == 0) { r = r | (r << (1 << variableNumber)); } else { r = r | (r >> (1 << variableNumber)); } return r; } /** * Determine if a variable is still in a relation. * * @param relationNumber * Relation to check * @param variableNumber * Variable position to check * @return True if the variable is still in the relation */ public static boolean isVariableNotInRelation(int relationNumber, int variableNumber) { int r0 = reduce(relationNumber, variableNumber, 0); int r1 = reduce(relationNumber, variableNumber, 1); return (r0 == r1); } /** * Determine how many variables are still in a relation. * * @param relationNumber * Relation to check * @return Number of variables in relation */ public static int variablesInRelation(int relationNumber) { int rank = 3; for (int i = 0; i < 3; i++) { if (isVariableNotInRelation(relationNumber, i)) { rank--; } } return rank; } /** * Determine how many rows in the relation's truth table evaluate to true * given s variables set to true. * * @param relationNumber * Relation to check * @param sub * Number of variables set to true * @return Number of rows that evaluate to true */ public static int q(int relationNumber, int sub/* 0,1,2,3 */) { int m; switch (sub) { case 0: m = 1; break; case 1: m = 22; break; case 2: m = 104; break; case 3: m = 128; break; default: m = 0; System.out.println("Sub can be 0,1,2,or 3"); } return ones((relationNumber & m)); } /** * Determine the total number of rows in the relation's truth table that * evaluate to true. * * @param relationNumber * Relation check * @return Number of rows that evaluate to true. */ public static int ones(int relationNumber) { int c = 0; for (int i = 0; i < 8; i++) { if ((relationNumber & (1 << i)) != 0) { c++; } } return c; } /** * Determine the magic number for a variable position and value. * * @param variableNumber * Variable position * @param value * Value * @return Magic number */ private static int getMagicNumber(int variableNumber, int value) { // ToDo: use xor, see if there is a default return value if (value == 0) { if (variableNumber == 0) { return 85; /* 1st var (Least Significant), value 0 */ } if (variableNumber == 1) { return 51; } if (variableNumber == 2) { return 15; /* last var (Most Significant), value 0 */ } System.out.println("Only 3 variable Numbers are allowed 0,1,2"); } else if (value == 1) { if (variableNumber == 0) { return 170; /* 1st var (Least Significant), value 1 */ } if (variableNumber == 1) { return 204; } if (variableNumber == 2) { return 240; /* last var (Most Significant), value 0 */ } System.out.println("Only 3 variable Numbers are allowed 0,1,2"); } else { System.out.println("Only 0 or 1 are allowed as values"); } return -1; } }