![JAR search and dependency download from the Maven repository](/logo.png)
org.ggp.base.util.Odometer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of alloy-ggp-base Show documentation
Show all versions of alloy-ggp-base Show documentation
A modified version of the GGP-Base library for Alloy.
The newest version!
package org.ggp.base.util;
import java.util.Iterator;
import java.util.List;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
//Not thread-safe
/**
* The Odometer is a way of iterating through a Cartesian product.
*
* The 0-indexed value will update most often, followed by the 1-index,
* and so on.
*
* Odometer is not thread-safe.
*/
public class Odometer implements Iterator> {
private final List odometer;
private final ImmutableList> values;
private final ImmutableList> valuesIndex;
public Odometer(ImmutableList> values,
ImmutableList> valuesIndex) {
Preconditions.checkArgument(values.size() > 0, "The size of an odometer cannot be 0");
this.values = values;
this.valuesIndex = valuesIndex;
this.odometer = Lists.newArrayListWithCapacity(values.size());
for (int i = 0; i < values.size(); i++) {
odometer.add(0);
}
}
public static Odometer create(List> values) {
ImmutableList> immutableValues = values.stream()
.map(ImmutableList::copyOf)
.collect(Immutables.collectList());
ImmutableList> valuesIndex = values.stream()
.map(AlloyUtils::getListIndex)
.collect(Immutables.collectList());
return new Odometer(immutableValues, valuesIndex);
}
@Override
public boolean hasNext() {
int lastIndex = values.size() - 1;
return odometer.get(lastIndex) < values.get(lastIndex).size();
}
@Override
public List next() {
List result = collectValues();
increment();
return result;
}
private void increment() {
increment(0);
}
private void increment(int slotToUpdate) {
Preconditions.checkElementIndex(slotToUpdate, odometer.size());
int lastIndex = odometer.size() - 1;
while (slotToUpdate < lastIndex) {
int curValue = odometer.get(slotToUpdate);
int numValues = values.get(slotToUpdate).size();
if (curValue + 1 < numValues) {
break;
}
slotToUpdate++;
}
int newValue = odometer.get(slotToUpdate) + 1;
odometer.set(slotToUpdate, newValue);
for (int i = 0; i < slotToUpdate; i++) {
odometer.set(i, 0);
}
}
private List collectValues() {
List result = Lists.newArrayListWithCapacity(values.size());
for (int i = 0; i < values.size(); i++) {
int curIndex = odometer.get(i);
T valueForSlot = values.get(i).get(curIndex);
result.add(valueForSlot);
}
return result;
}
public void skipPastValueInSlot(int slot, T value) {
int odometerValue = valuesIndex.get(slot).get(value);
skipPastValueInSlot(slot, odometerValue);
}
private void skipPastValueInSlot(int slot, int odometerValue) {
if (odometer.get(slot) == odometerValue) {
increment(slot);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy