/* * CSP Project * Authors: * Jay Bernardo * Matt Rancourt * * File: SSRelation.java * * Contains the SSRelation class. * A SSRelation is essentially just a relation with special * goodness representation meaning that it is an OR relation * of size > 3 munged into size 3. It will do lookups accordingly * the truth table satisfaction given some number of variables * as input. * * This class is solely for use with semisuperresolution * */ import java.util.ArrayList; import java.util.Iterator; class SSRelation extends Relation{ ArrayList mungedVariables; /** * Changes the given list of variableNamesIn to be of * the format that the SSRelation constructor expects * * @param variableNamesIn - Array of variable names in non munged format * @return a new array of variableNames for use with SSRelation constructor */ public static String[] mungeVariableNamesIn(String variableNamesIn[]){ String keepVariables[] = new String[3]; keepVariables[0] = new String(variableNamesIn[0]); keepVariables[1] = new String(variableNamesIn[1]); keepVariables[2] = new String(""); int i = 2; for(; i < variableNamesIn.length; i ++){ keepVariables[2] = String.format("%s%s", keepVariables[2], variableNamesIn[i]); } return keepVariables; } /** * This function creates a list of the special "munged" variables * that are put into the third variable spot that represent the Or of the * extra variables * * @param variableNamesIn - list of original variable names to examing * @return ArrayList containing the extra variables for use with the SSRelation constructor * @throws InvalidVariableValueException */ public static ArrayList mungedVariablesList(String variableNamesIn[]) throws InvalidVariableValueException{ ArrayList list = new ArrayList(); int i = 2; for(; i < variableNamesIn.length; i ++){ Variable newVar = null; boolean positive = true; if(variableNamesIn[i].charAt(0) == '!'){ positive = false; } String name = null; if(positive){ name = new String(variableNamesIn[i]); } else{ name = new String(variableNamesIn[i].substring(1)); } newVar = new Variable(name, -1, positive); list.add(newVar); } return list; } /** * Constructor for a relation * * @param relationNumber - the number of the given relation * @param rank - the rank of the relation (1, 2, or 3) * @param variableNamesIn - names of the variables */ public SSRelation(int relationNumber, int rank, String variableNamesIn[], ArrayListmungedVariables) throws RelationNumberOutOfBoundsException, RankOutOfBoundsException, InvalidVariableNamesLengthException, InvalidVariableValueException{ super(relationNumber, rank, variableNamesIn); // Now, for the rest of the variables this.mungedVariables = mungedVariables; } /** * Sets the variable varName to the given value, * if it exists in the relation * @param varName - name of variable to set value for * @param value - value to assign to the given variable */ public void setVariable(String varName, int value) throws InvalidVariableValueException{ int i = 0; for(; i < 2; i ++){ if(variables[i].getName().equals(varName)){ variables[i].setValue(value); } } Iteratorit = mungedVariables.iterator(); while(it.hasNext()){ Variable v = it.next(); if(v.getName().equals(varName)){ v.setValue(value); } } } /** * Returns the name of the first variable which is unassigned * @return name of first unassigned variable or * null if all variables are assigned */ public String findUnassignedVariable(){ int i = 0; for(; i < 2; i ++){ if(variables[i].getValue() == -1){ return variables[i].getName(); } } Iteratorit = mungedVariables.iterator(); while(it.hasNext()){ Variable v = it.next(); if(v.getValue() == -1){ return v.getName(); } } return null; } /** * Returns a duplicate of "this" Relation * @return a copy of the relation "this" * @throws RelationNumberOutOfBoundsException * @throws RankOutOfBoundsException * @throws InvalidVariableNamesLengthException * * TODO: This is almost a complete copy of what * reduce does. This should be extrapolated * into helper methods */ public Relation duplicate() throws RelationNumberOutOfBoundsException, RankOutOfBoundsException, InvalidVariableNamesLengthException, InvalidVariableValueException { ArrayListnewMungedVariables = new ArrayList(); if(variables[0].getValue() == -1){ newMungedVariables.add(variables[0]); } if(variables[1].getValue() == -1){ newMungedVariables.add(variables[1]); } Iteratorit = mungedVariables.iterator(); while(it.hasNext()){ Variable v = it.next(); // Keep it if it's unassigned if(v.getValue() == -1){ newMungedVariables.add(v); } } // Determine the variable names of newness! String variableNames[] = new String[newMungedVariables.size()]; Iteratorjt = newMungedVariables.iterator(); int j = 0; while(jt.hasNext()){ Variable v = jt.next(); String varName = new String(v.getName()); // IF the variable is negative if(v.getPositive() == false){ varName = String.format("!%s", varName); } variableNames[j] = varName; j ++; } return new SSRelation(254, 3, SSRelation.mungeVariableNamesIn(variableNames), SSRelation.mungedVariablesList(variableNames)); } /** * Reduces this Relation according to which * variables have set values. * @return - reduced Relation */ public Relation reduce() throws RelationNumberOutOfBoundsException, RankOutOfBoundsException, InvalidVariableNamesLengthException, InvalidVariableValueException{ if(isSatisfied()){ return this; } ArrayListnewMungedVariables = new ArrayList(); if(variables[0].getValue() == -1){ newMungedVariables.add(variables[0]); } if(variables[1].getValue() == -1){ newMungedVariables.add(variables[1]); } Iteratorit = mungedVariables.iterator(); while(it.hasNext()){ Variable v = it.next(); // Keep it if it's unassigned if(v.getValue() == -1){ newMungedVariables.add(v); } } // Determine the variable names of newness! String variableNames[] = new String[newMungedVariables.size()]; Iteratorjt = newMungedVariables.iterator(); int j = 0; while(jt.hasNext()){ Variable v = jt.next(); String varName = new String(v.getName()); // IF the variable is negative if(v.getPositive() == false){ varName = String.format("!%s", varName); } variableNames[j] = varName; j ++; } if(newMungedVariables.size() <= 3){ int rank = newMungedVariables.size(); relationNumber = 0; if(rank == 1){ relationNumber = 2; } else if(rank == 2){ relationNumber = 14; } else{ relationNumber = 254; } Relation r = new Relation(relationNumber, rank, variableNames); return r.preprocess(); } else{ // We need to turn all the variables to positives int negatives = 0; boolean slot1 = false; boolean slot2 = false; if(variableNames[0].charAt(0) == '!'){ // Remove the negativity variableNames[0] = String.format("%s", variableNames[0].substring(1)); negatives ++; slot1 = true; } if(variableNames[1].charAt(0) == '!'){ // Remove the negativity variableNames[1] = String.format("%s", variableNames[1].substring(1)); negatives ++; slot2 = true; } int relationNumber = 254; if(negatives == 1){ if(slot1) relationNumber = 239; else if(slot2) relationNumber = 251; } else if(negatives == 2) relationNumber = 191; return new SSRelation(relationNumber, 3, SSRelation.mungeVariableNamesIn(variableNames), SSRelation.mungedVariablesList(variableNames)); //return new SSRelation(254, 3, SSRelation.mungeVariableNamesIn(variableNames), // SSRelation.mungedVariablesList(variableNames)); } } /** * Returns whether the relation is deemed * unsatisfied or not * @return true if all variables are set, but the relation is unsatisfied with the given assignment * false otherwise */ public boolean isUnsatisfied(){ if(variables[0].getValue() != -1 || variables[1].getValue() != -1){ return false; } Iterator it = mungedVariables.iterator(); while(it.hasNext()){ Variable v = it.next(); if(v.getValue() != -1){ return false; } } return !isSatisfied(); } /** * Returns whether the SSRelation is satisfied or not * @return true if the relation is satisfied with all variables set * false otherwise */ public boolean isSatisfied(){ if(variables[0].getValue() == 1 || variables[1].getValue() == 1){ return true; } Iteratorit = mungedVariables.iterator(); while(it.hasNext()){ if(it.next().getValue() == 1){ return true; } } return false; } }