package edu.ucsd.arcum.interpreter.query; import static edu.ucsd.arcum.util.StringUtil.separate; import java.util.Collection; import java.util.List; import java.util.Set; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import edu.ucsd.arcum.exceptions.ArcumError; import edu.ucsd.arcum.interpreter.ast.FormalParameter; import edu.ucsd.arcum.interpreter.ast.TraitSignature; import edu.ucsd.arcum.interpreter.satisfier.BindingMap; import edu.ucsd.arcum.interpreter.satisfier.BindingsSet; public class TraitValue { private final String traitName; private final TraitSignature traitType; private final Set<EntityTuple> entities; private final boolean isStatic; private final boolean isNested; public TraitValue(String traitName, TraitSignature tupleSetType) { this(traitName, tupleSetType, false, false); } public TraitValue(String traitName, TraitSignature tupleSetType, boolean isStatic, boolean isNested) { this.traitName = traitName; this.traitType = tupleSetType; this.entities = Sets.newTreeSet(); this.isStatic = isStatic; this.isNested = isNested; } public EntityTuple getSingleton() { if (entities.size() != 1) { ArcumError.fatalError("Non-singleton"); } return entities.iterator().next(); } public List<EntityTuple> getEntities() { return Lists.newArrayList(entities); } // Returns true if this set did not already contain the specified element public boolean addTuple(EntityTuple entityTuple) { return entities.add(entityTuple); } @Override public String toString() { return String.format("{%s}", separate(entities, String.format("%n "))); } public String getTraitName() { return traitName; } public TraitSignature getTraitType() { return traitType; } public boolean isStatic() { return isStatic; } public boolean isNested() { return isNested; } public Collection<String> getNamesOfDeclaredFormals() { return traitType.getNamesOfDeclaredFormals(); } // An arg in the "args" list is either a program entity or a VariablePlaceholder. // Arguments are assumed to be in order. public BindingsSet getMatches(List<Object> args, BindingMap in) { List<FormalParameter> formals = traitType.getFormals(); BindingsSet result = BindingsSet.newEmptySet(); for (EntityTuple entity : entities) { BindingMap theta = entity.matches(formals, args); if (theta != null) { result.addEntry(theta); } } for (BindingMap bindingMap : result) { // We add these later so that addEntry doesn't have to compare as many // items bindingMap.addBindings(in); } return result; } }