001package org.clafer.choco.constraint.propagator;
002
003import java.util.Arrays;
004import solver.constraints.Propagator;
005import solver.constraints.PropagatorPriority;
006import solver.exception.ContradictionException;
007import solver.variables.EventType;
008import solver.variables.SetVar;
009import util.ESat;
010
011/**
012 *
013 * @author jimmy
014 */
015public class PropSortedSets extends Propagator<SetVar> {
016
017    private final SetVar[] sets;
018
019    public PropSortedSets(SetVar[] sets) {
020        super(sets, PropagatorPriority.LINEAR, false);
021        this.sets = sets;
022    }
023
024    @Override
025    protected int getPropagationConditions(int vIdx) {
026        return EventType.ADD_TO_KER.mask;
027    }
028
029    @Override
030    public void propagate(int evtmask) throws ContradictionException {
031        // Right now, it don't does a very simple propagation. It does not
032        // enforce sorted sets by itself, requires PropSortedSetsCard in conjunction.
033        // Can make it better if necessary but might turn out slower.
034        for (int i = 0; i < sets.length; i++) {
035            SetVar set = sets[i];
036            int cur = set.getKernelFirst();
037            if (cur != SetVar.END) {
038                for (int next = set.getKernelNext(); next != SetVar.END; next = set.getKernelNext()) {
039                    for (int j = cur + 1; j < next; j++) {
040                        set.addToKernel(j, aCause);
041                    }
042                }
043            }
044        }
045    }
046
047    @Override
048    public void propagate(final int idxVarInProp, int mask) throws ContradictionException {
049        forcePropagate(EventType.FULL_PROPAGATION);
050    }
051
052    @Override
053    public ESat isEntailed() {
054        for (int i = 0; i < sets.length; i++) {
055            SetVar set = sets[i];
056            int cur = set.getKernelFirst();
057            if (cur != SetVar.END) {
058                for (int next = set.getKernelNext(); next != SetVar.END; next = set.getKernelNext()) {
059                    for (int j = cur + 1; cur < next; cur++) {
060                        if (!set.envelopeContains(j)) {
061                            return ESat.FALSE;
062                        }
063                    }
064                }
065            }
066        }
067        return isCompletelyInstantiated() ? ESat.TRUE : ESat.UNDEFINED;
068    }
069
070    @Override
071    public String toString() {
072        return "sortedSets(" + Arrays.toString(sets) + ")";
073    }
074}