This repository has been archived on 2025-03-02. You can view files and clone it, but cannot push or open issues or pull requests.
JRummikub/src/jrummikub/ai/fdsolver/constraint/IndexConstraint.java
Jannis Harder 99c3d48f10 Several speed optimizations
git-svn-id: svn://sunsvr01.isp.uni-luebeck.de/swproj13/trunk@438 72836036-5685-4462-b002-a69064685172
2011-06-14 17:48:26 +02:00

140 lines
3.2 KiB
Java

package jrummikub.ai.fdsolver.constraint;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import org.w3c.dom.ranges.Range;
import jrummikub.ai.fdsolver.Constraint;
import jrummikub.ai.fdsolver.Propagator;
import jrummikub.ai.fdsolver.Satisfiability;
import jrummikub.ai.fdsolver.Var;
public class IndexConstraint<T> extends Constraint {
Var<T> target;
Var<Integer> index;
List<Var<T>> list;
Collection<Var<?>> vars = new ArrayList<Var<?>>();
Collection<Var<?>> varsNoTarget = new ArrayList<Var<?>>();
Collection<Var<?>> varsNoIndex = new ArrayList<Var<?>>();
public IndexConstraint(Var<T> target, Var<Integer> index, List<Var<T>> list) {
this.target = target;
this.index = index;
this.list = list;
vars.addAll(list);
vars.add(index);
vars.add(target);
varsNoTarget.addAll(list);
varsNoTarget.add(index);
varsNoIndex.addAll(list);
varsNoIndex.add(target);
}
@Override
public Collection<Var<?>> getWatchedVars() {
return vars;
}
private class UnionProp implements Propagator {
@Override
public Collection<Var<?>> getWatchedVars() {
return varsNoTarget;
}
@Override
public void propagate() {
HashSet<T> invUnion = new HashSet<T>(target.getRange());
for (int i : index.getRange()) {
invUnion.removeAll(list.get(i).getRange());
if (invUnion.isEmpty()) {
return;
}
}
for (T val : invUnion) {
target.invalidate(val);
}
};
}
private class IndexProp implements Propagator {
@Override
public Collection<Var<?>> getWatchedVars() {
return varsNoIndex;
}
@Override
public void propagate() {
for (Iterator<Integer> i = index.iterator(); i.hasNext();) {
int id = i.next();
Var<T> item = list.get(id);
if (Collections.disjoint(item.getRange(), target.getRange())) {
i.remove();
}
}
}
}
private class VarProp implements Propagator {
@Override
public Collection<Var<?>> getWatchedVars() {
return Arrays.asList(target, index);
}
@Override
public void propagate() {
if (index.getRange().size() != 1)
return;
int id = index.getValue();
Var<T> var = list.get(id);
for(Iterator<T> i = var.iterator(); i.hasNext();) {
if (!target.getRange().contains(i.next())) {
i.remove();
}
}
}
}
@Override
public Collection<Propagator> getPropagators(boolean negate) {
if (negate) {
return Collections.emptyList();
}
return Arrays.<Propagator> asList(new UnionProp(), new IndexProp(), new VarProp());
}
@Override
public boolean isSatisfiable() {
for (int i : index.getRange()) {
if(!Collections.disjoint(list.get(i).getRange(), target.getRange())) {
return true;
}
}
return false;
}
@Override
public Satisfiability getSatisfiability() {
boolean sat = isSatisfiable();
if (!sat) {
return Satisfiability.UNSAT;
}
if (target.getRange().size() > 1)
return Satisfiability.SAT;
for (int i : index.getRange()) {
Var<T> var = list.get(i);
if (var.getRange().size() > 1)
return Satisfiability.SAT;
if(var.getValue() != target.getValue()) {
return Satisfiability.SAT;
}
}
return Satisfiability.TAUT;
}
}