package models.dataConstraintModel;
import models.algebra.Constant;
import models.algebra.Expression;
import models.algebra.Symbol;
import models.algebra.Term;
import parser.Parser;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class MapTerm extends Term {
private Map<String, Integer> keyToIndex = new HashMap<>();
public MapTerm() {
super(new Symbol("map", -1));
setType(DataConstraintModel.typeMap);
}
public void insert(String key, Expression value) {
if (keyToIndex.containsKey(key)) {
setChild(keyToIndex.get(key), value);
} else {
keyToIndex.put(key, getChildren().size());
addChild(value);
}
}
public Set<String> keySet() {
return keyToIndex.keySet();
}
public Expression get(String key) {
return getChild(keyToIndex.get(key));
}
public Expression get(Constant key) {
if (keyToIndex.get(key.getValue()) == null) return null;
return getChild(keyToIndex.get(key.getValue()));
}
@Override
public Expression unify(Expression another) {
if (another instanceof MapTerm) {
MapTerm anotherTerm = (MapTerm) another;
MapTerm unifiedTerm = new MapTerm();
Set<String> keySet = new HashSet<>();
keySet.addAll(this.keySet());
keySet.addAll(anotherTerm.keySet());
for (String key : keySet) {
if (this.keySet().contains(key)) {
if (anotherTerm.keySet().contains(key)) {
unifiedTerm.insert(key, this.get(key).unify(anotherTerm.get(key)));
} else {
unifiedTerm.insert(key, this.get(key));
}
} else {
unifiedTerm.insert(key, anotherTerm.get(key));
}
}
return unifiedTerm;
}
return this;
}
@Override
public Object clone() {
MapTerm newTerm = new MapTerm();
for (Expression e : children) {
newTerm.addChild((Expression) e.clone());
}
newTerm.keyToIndex = new HashMap<String, Integer>(keyToIndex);
return newTerm;
}
public String toString() {
String mapStr = "{";
String delim = "";
for (String key : keyToIndex.keySet()) {
mapStr += delim + Parser.DOUBLE_QUOT + key + Parser.DOUBLE_QUOT + ": " + getChild(keyToIndex.get(key)).toString();
delim = ", ";
}
return mapStr + "}";
}
}