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}