org.ggp.base.util.gdl.model.assignments.FunctionInfoImpl 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.gdl.model.assignments;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.ggp.base.util.concurrency.ConcurrencyUtils;
import org.ggp.base.util.gdl.GdlUtils;
import org.ggp.base.util.gdl.grammar.GdlConstant;
import org.ggp.base.util.gdl.grammar.GdlSentence;
import org.ggp.base.util.gdl.grammar.GdlTerm;
import org.ggp.base.util.gdl.grammar.GdlVariable;
import org.ggp.base.util.gdl.model.SentenceForm;
import org.ggp.base.util.gdl.transforms.ConstantChecker;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
//Represents information about a sentence form that is constant.
public class FunctionInfoImpl implements FunctionInfo {
private final SentenceForm form;
//True iff the slot has at most one value given the other slots' values
private final ImmutableList dependentSlots;
private final ImmutableList, GdlConstant>> valueMaps;
private FunctionInfoImpl(SentenceForm form, ImmutableList dependentSlots,
ImmutableList, GdlConstant>> valueMaps) {
this.form = form;
this.dependentSlots = dependentSlots;
this.valueMaps = valueMaps;
}
@Override
public Map, GdlConstant> getValueMap(int index) {
Preconditions.checkArgument(dependentSlots.get(index));
return valueMaps.get(index);
}
@Override
public List getDependentSlots() {
return dependentSlots;
}
/**
* Given a sentence of the constant form's sentence form, finds all
* the variables in the sentence that can be produced functionally.
*
* Note the corner case: If a variable appears twice in a sentence,
* it CANNOT be produced in this way.
*/
@Override
public Set getProducibleVars(GdlSentence sentence) {
if(!form.matches(sentence))
throw new RuntimeException("Sentence "+sentence+" does not match constant form");
List tuple = GdlUtils.getTupleFromSentence(sentence);
Set candidateVars = new HashSet();
//Variables that appear multiple times go into multipleVars
Set multipleVars = new HashSet();
//...which, of course, means we have to spot non-candidate vars
Set nonCandidateVars = new HashSet();
for(int i = 0; i < tuple.size(); i++) {
GdlTerm term = tuple.get(i);
if(term instanceof GdlVariable
&& !multipleVars.contains(term)) {
GdlVariable var = (GdlVariable) term;
if(candidateVars.contains(var)
|| nonCandidateVars.contains(var)) {
multipleVars.add(var);
candidateVars.remove(var);
} else if(dependentSlots.get(i)) {
candidateVars.add(var);
} else {
nonCandidateVars.add(var);
}
}
}
return candidateVars;
}
public static FunctionInfo create(SentenceForm form,
ConstantChecker constantChecker) throws InterruptedException {
return create(form, ImmutableSet.copyOf(constantChecker.getTrueSentences(form)));
}
public static FunctionInfo create(SentenceForm form,
Set trueSentences) throws InterruptedException {
int numSlots = form.getTupleSize();
List dependentSlots = Lists.newArrayList();
List, GdlConstant>> valueMaps = Lists.newArrayList();
for(int i = 0; i < numSlots; i++) {
//We want to establish whether or not this is a constant...
Map, GdlConstant> functionMap = Maps.newHashMap();
boolean functional = true;
for (GdlSentence sentence : trueSentences) {
ConcurrencyUtils.checkForInterruption();
List tuple = GdlUtils.getTupleFromGroundSentence(sentence);
List tuplePart = Lists.newArrayListWithCapacity(tuple.size() - 1);
tuplePart.addAll(tuple.subList(0, i));
tuplePart.addAll(tuple.subList(i + 1, tuple.size()));
if(functionMap.containsKey(tuplePart)) {
//We have two tuples with different values in just this slot
functional = false;
break;
}
//Otherwise, we record it
functionMap.put(ImmutableList.copyOf(tuplePart), tuple.get(i));
}
if(functional) {
//Record the function
dependentSlots.add(true);
valueMaps.add(ImmutableMap.copyOf(functionMap));
} else {
//Forget it
dependentSlots.add(false);
valueMaps.add(ImmutableMap.of());
}
}
return new FunctionInfoImpl(form,
ImmutableList.copyOf(dependentSlots),
ImmutableList.copyOf(valueMaps));
}
@Override
public SentenceForm getSentenceForm() {
return form;
}
@Override
public String toString() {
return "FunctionInfoImpl [form=" + form + ", dependentSlots="
+ dependentSlots + ", valueMaps=" + valueMaps + "]";
}
public static Map createMap(
ConstantChecker constantChecker) throws InterruptedException {
ImmutableMap.Builder result = ImmutableMap.builder();
for (SentenceForm constantForm : constantChecker.getConstantSentenceForms()) {
result.put(constantForm, create(constantForm, constantChecker));
}
return result.build();
}
}