001package org.clafer.choco.constraint.propagator; 002 003import org.clafer.common.Util; 004import solver.constraints.Propagator; 005import solver.constraints.PropagatorPriority; 006import solver.exception.ContradictionException; 007import solver.variables.BoolVar; 008import solver.variables.EventType; 009import util.ESat; 010 011/** 012 * 013 * @author jimmy 014 */ 015public class PropLone extends Propagator<BoolVar> { 016 017 public PropLone(BoolVar[] vars) { 018 super(vars, PropagatorPriority.BINARY, true); 019 } 020 021 @Override 022 public int getPropagationConditions(int vIdx) { 023 return EventType.INSTANTIATE.mask; 024 } 025 026 private void clearAllBut(int exclude) throws ContradictionException { 027 for (int i = 0; i < vars.length; i++) { 028 if (i != exclude) { 029 vars[i].setToFalse(aCause); 030 } 031 } 032 } 033 034 @Override 035 public void propagate(int evtmask) throws ContradictionException { 036 for (int i = 0; i < vars.length; i++) { 037 BoolVar var = vars[i]; 038 if (var.instantiated()) { 039 if (var.getValue() == 1) { 040 clearAllBut(i); 041 return; 042 } 043 } 044 } 045 } 046 047 @Override 048 public void propagate(int idxVarInProp, int mask) throws ContradictionException { 049 assert EventType.isInstantiate(mask); 050 if (vars[idxVarInProp].getValue() == 1) { 051 clearAllBut(idxVarInProp); 052 } 053 } 054 055 @Override 056 public ESat isEntailed() { 057 int count = 0; 058 boolean allInstantiated = true; 059 for (BoolVar var : vars) { 060 if (var.instantiated()) { 061 if (var.getValue() == 1) { 062 count++; 063 if (count > 1) { 064 return ESat.FALSE; 065 } 066 } 067 } else { 068 allInstantiated = false; 069 } 070 } 071 return allInstantiated ? ESat.TRUE : ESat.UNDEFINED; 072 } 073 074 @Override 075 public String toString() { 076 return "lone(" + Util.commaSeparate(vars) + ")"; 077 } 078}