/* * CSP Project * Authors: * Jay Bernardo * Matt Rancourt * * File: UnitPropagate.java * * Contains the UnitPropagate class. * * TODO: * * - Update description */ class UnitPropagate extends Transition{ //HashMap updatePairs; public UnitPropagate(TransitionAssignment M, CSP F){ super(M, F); } /** * Does the work of the transition. This essentially works * in the following way: In each call to UP we iterate through * the list of relations, setting the last variable in M. We then * proceed to reduce the given relation. After reduction, we check * forcedness. If a variable is forced, we add it to M. * * While iterating through the relations, if something has been * previously added to M, we don't bother reducing or forced checking, * we simply set the current variable we are looking at and iterate * to the end. * * NOTE: UnitPropagate is the only transition that assigns variables * in F to some value * * @return -1 if cannot be applied again with results * 0 if can possibly be applied again with results * 1 if semi-superresolution needs to be called */ public int doTransition() throws InvalidVariableValueException, RelationNumberOutOfBoundsException, RankOutOfBoundsException, InvalidVariableNamesLengthException, VariablePositionOutOfBoundsException{ int i = 0; boolean done = false; for(;i < F.numberOfRelations(); i ++){ Relation currentRelation = F.getRelationAt(i); if(M.numberOfVariables() > 0){ TransitionAssignmentVariable lastVar = M.getVariableAt(M.numberOfVariables()-1); currentRelation.setVariable(lastVar.getName(), lastVar.getValue()); } if(M.containsADecidedVariable && currentRelation.isUnsatisfied()){ return 1; } if(!currentRelation.isSatisfied() && !done) { // Reude the relation Relation newRelation = currentRelation.reduce(); int numberOfVariables = newRelation.getRank(); int k = 1; for(; k <= numberOfVariables; k ++){ int forced = Relation.forced(newRelation.getRelationNumber(), numberOfVariables, k); // We need to reverse the value if it's a negative variable // because when we set a negative variable it sets inverse // we want that inversion set to inverse to the proper thing int forcedValue = forced; if(newRelation.variables[k-1].getPositive() == false){ if(forced == 0) forcedValue = 1; else forcedValue = 0; } if(forced != -1){ TransitionAssignmentVariable newVariable = new TransitionAssignmentVariable( newRelation.variables[k-1].getName(), forcedValue, newRelation.variables[k-1].getPositive(), false); M.add(newVariable); done = true; break; } } } } // If we end up here and done is still false, that means we've // checked all options and there was no work to do if(done == false){ return -1; } return 0; } }