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 PropOr extends Propagator<BoolVar> {
016
017    public PropOr(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    @Override
027    public void propagate(int evtmask) throws ContradictionException {
028        // The number of uninstantiated variables.
029        int count = 0;
030        BoolVar last = null;
031        for (BoolVar var : vars) {
032            if (var.instantiated()) {
033                if (var.getValue() == 1) {
034                    setPassive();
035                    return;
036                }
037            } else {
038                count++;
039                last = var;
040            }
041        }
042        // Every variable if false except for last.
043        if (count == 1) {
044            last.setToTrue(aCause);
045        }
046        if (count == 0) {
047            contradiction(vars[0], "All false.");
048        }
049    }
050
051    @Override
052    public void propagate(int idxVarInProp, int mask) throws ContradictionException {
053        assert EventType.isInstantiate(mask);
054        if (vars[idxVarInProp].getValue() == 1) {
055            setPassive();
056        } else {
057            propagate(mask);
058        }
059    }
060
061    @Override
062    public ESat isEntailed() {
063        boolean allInstantiated = true;
064        for (BoolVar var : vars) {
065            if (var.instantiated()) {
066                if (var.getValue() == 1) {
067                    return ESat.TRUE;
068                }
069            } else {
070                allInstantiated = false;
071            }
072        }
073        return allInstantiated ? ESat.FALSE : ESat.UNDEFINED;
074    }
075
076    @Override
077    public String toString() {
078        return Util.intercalate(" or ", vars);
079    }
080}