/////////////////////////////////////////////////////////////////////// // STANFORD LOGIC GROUP // // General Game Playing Project // // // // Sample Player Implementation // // // // (c) 2007. See LICENSE and CONTRIBUTORS. // /////////////////////////////////////////////////////////////////////// package stanfordlogic.util; import java.util.Iterator; import java.util.List; import stanfordlogic.knowledge.FactProcessor; import stanfordlogic.prover.GroundFact; /** * Generates combinations of facts. Used to generate all combinations of several * lists of facts, keeping one fact constant. Given the constant fact and * several lists of facts, generates all combinations that can be formed of the * constant fact and a fact from each list of facts. * * @author Based on code by Team Camembert: David Haley, Pierre-Yves Laligand */ public class FactCombinationIterator implements Iterator<GroundFact[]>, Iterable<GroundFact[]> { private boolean endOfIteration_; private int[] currentIndeces_; private GroundFact[] currentFacts_; private List<List<GroundFact>> items_; private FactProcessor processor_; private int changeLevels_; private static final FactProcessor dummyProcessor = new FactProcessor() { @Override public GroundFact processFact(GroundFact fact) { return fact; } }; /** * * * @param staticFact The fact that will appear in all results. * @param items The facts from which to generate combinations. */ public FactCombinationIterator(GroundFact staticFact, List<List<GroundFact>> items) { this(staticFact, items, dummyProcessor); } /** * * * @param staticFact The fact that will appear in all results. * @param items The facts from which to generate combinations. * @param processor The processor to apply to all facts. */ public FactCombinationIterator(GroundFact staticFact, List<List<GroundFact>> items, FactProcessor processor) { processor_ = processor; items_ = items; currentIndeces_ = new int[items_.size() + 1]; currentFacts_ = new GroundFact[items_.size() + 1]; currentFacts_[0] = processor.processFact(staticFact); changeLevels_ = items_.size(); } public GroundFact[] next() { prepareFacts(); prepareNextIndeces(); return currentFacts_; } private void prepareNextIndeces() { changeLevels_ = 0; incrementIndex(currentIndeces_.length - 1); } private void incrementIndex(int index) { if(index <= 0) { endOfIteration_ = true; return; } changeLevels_++; int newIndexValue = currentIndeces_[index] + 1; if(newIndexValue >= items_.get(index-1).size()) { currentIndeces_[index] = 0; incrementIndex(index - 1); } else { currentIndeces_[index] = newIndexValue; } } private void prepareFacts() { for(int i=0; i<changeLevels_; i++) { int index = currentFacts_.length - 1 - i; currentFacts_[index] = processor_.processFact(items_.get(index-1).get(currentIndeces_[index])); } } public boolean hasNext() { return !endOfIteration_; } public Iterator<GroundFact[]> iterator() { return this; } public void remove() { } }