package models.dataConstraintModel; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Set; import models.algebra.Symbol; import models.algebra.Type; import parser.Parser; public class DataConstraintModel { protected HashMap<String, IdentifierTemplate> identifierTemplates = null; protected HashMap<String, ChannelGenerator> channelGenerators = null; protected HashMap<String, ChannelGenerator> ioChannelGenerators = null; protected HashMap<String, Type> types = null; protected HashMap<String, Symbol> symbols = null; public static final Type typeInt = new Type("Int", "int"); public static final Type typeLong = new Type("Long", "long"); public static final Type typeFloat = new Type("Float", "float"); public static final Type typeDouble = new Type("Double", "double"); public static final Type typeBoolean = new Type("Bool", "boolean"); public static final Type typeString = new Type("Str", "String"); public static final Type typeList = new Type("List", "ArrayList", "List"); public static final Type typeListInt = new Type("List", "ArrayList<>", "List<Integer>", typeList); public static final Type typeListStr = new Type("List", "ArrayList<>", "List<String>", typeList); public static final Type typeTuple = new Type("Tuple", "AbstractMap.SimpleEntry", "Map.Entry"); public static final Symbol add = new Symbol(Parser.ADD, 2, Symbol.Type.INFIX); public static final Symbol mul = new Symbol(Parser.MUL, 2, Symbol.Type.INFIX);; public static final Symbol sub = new Symbol(Parser.SUB, 2, Symbol.Type.INFIX); public static final Symbol div = new Symbol(Parser.DIV, 2, Symbol.Type.INFIX); public static final Symbol minus = new Symbol(Parser.MINUS, 1); public static final Symbol cons = new Symbol("cons", 2, Symbol.Type.PREFIX, "($x,$y)->$x.add(0, $y)", Symbol.Type.LAMBDA_WITH_SIDE_EFFECT, new int[] {1, 0}); public static final Symbol head = new Symbol("head", 1, Symbol.Type.PREFIX, "($x)->$x.get(0)", Symbol.Type.LAMBDA); public static final Symbol tail = new Symbol("tail", 1, Symbol.Type.PREFIX, "($x)->$x.subList(1, $x.size())", Symbol.Type.LAMBDA); public static final Symbol get = new Symbol("get", 2, Symbol.Type.PREFIX, "get", Symbol.Type.METHOD); public static final Symbol set = new Symbol("set", 3, Symbol.Type.PREFIX, "set", Symbol.Type.METHOD_WITH_SIDE_EFFECT); public static final Symbol contains = new Symbol("contains", 2, Symbol.Type.PREFIX, "contains", Symbol.Type.METHOD); public static final Symbol nil = new Symbol("nil", 0, Symbol.Type.PREFIX, new Symbol.IImplGenerator() { @Override public String generate(Type type, String[] children, String[] sideEffects) { String compType = ""; if (type != null) { String interfaceType = type.getInterfaceTypeName(); if (interfaceType.contains("<")) { compType = interfaceType.substring(interfaceType.indexOf("<") + 1, interfaceType.lastIndexOf(">")); } } return "new ArrayList<" + compType + ">()"; } }); public static final Symbol cond = new Symbol("if", 3, Symbol.Type.PREFIX, "($x,$y,$z)->($x ? $y : $z)", Symbol.Type.LAMBDA); public static final Symbol eq = new Symbol("eq", 2, Symbol.Type.PREFIX, "==", Symbol.Type.INFIX); public static final Symbol neq = new Symbol("neq", 2, Symbol.Type.PREFIX, "!=", Symbol.Type.INFIX); public static final Symbol gt = new Symbol("gt", 2, Symbol.Type.PREFIX, ">", Symbol.Type.INFIX); public static final Symbol lt = new Symbol("lt", 2, Symbol.Type.PREFIX, "<", Symbol.Type.INFIX); public static final Symbol tuple = new Symbol("tuple", -1, Symbol.Type.PREFIX, new Symbol.IImplGenerator() { @Override public String generate(Type type, String[] childrenImpl, String[] sideEffects) { String impl = "new AbstractMap.SimpleEntry<>(" + childrenImpl[0] + "$x)"; for (int i = 1; i < childrenImpl.length - 1; i++) { impl = impl.replace("$x", ", new AbstractMap.SimpleEntry<>(" + childrenImpl[i] + "$x)"); } impl = impl.replace("$x", ", " + childrenImpl[childrenImpl.length - 1]); return impl; } }); public static final Symbol fst = new Symbol("fst", 1, Symbol.Type.PREFIX, "getKey", Symbol.Type.METHOD); public static final Symbol snd = new Symbol("snd", 1, Symbol.Type.PREFIX, "getValue", Symbol.Type.METHOD); static { add.setInverses(new Symbol[] {sub, sub}); mul.setInverses(new Symbol[] {div, div}); sub.setInverses(new Symbol[] {add}); div.setInverses(new Symbol[] {mul}); minus.setInverses(new Symbol[] {minus}); cons.setInverses(new Symbol[] {head, tail}); cons.setSignature(new Type[] {typeList, null, typeList}); contains.setSignature(new Type[] {typeBoolean, typeList, null}); get.setSignature(new Type[] {null, typeList, typeInt}); set.setSignature(new Type[] {typeList, typeList, typeInt, null}); tuple.setSignature(new Type[] {typeTuple, null, null}); tuple.setInverses(new Symbol[] {fst, snd}); fst.setSignature(new Type[] {null, typeTuple}); snd.setSignature(new Type[] {null, typeTuple}); } public DataConstraintModel() { identifierTemplates = new HashMap<>(); channelGenerators = new HashMap<>(); ioChannelGenerators = new HashMap<>(); types = new HashMap<>(); addType(typeInt); addType(typeLong); addType(typeFloat); addType(typeDouble); addType(typeBoolean); addType(typeString); addType(typeList); addType(typeTuple); symbols = new HashMap<>(); addSymbol(add); addSymbol(mul); addSymbol(sub); addSymbol(div); addSymbol(minus); addSymbol(cons); addSymbol(head); addSymbol(tail); addSymbol(contains); addSymbol(get); addSymbol(set); addSymbol(nil); addSymbol(cond); addSymbol(eq); addSymbol(neq); addSymbol(gt); addSymbol(lt); addSymbol(tuple); addSymbol(fst); addSymbol(snd); } public Collection<IdentifierTemplate> getIdentifierTemplates() { return identifierTemplates.values(); } public IdentifierTemplate getIdentifierTemplate(String resourceName) { return identifierTemplates.get(resourceName); } public void addIdentifierTemplates(IdentifierTemplate identifierTemplate) { identifierTemplates.put(identifierTemplate.getResourceName(), identifierTemplate); } public void setIdentifierTemplates(HashMap<String, IdentifierTemplate> identifierTemplates) { this.identifierTemplates = identifierTemplates; } public Collection<ChannelGenerator> getChannelGenerators() { return channelGenerators.values(); } public ChannelGenerator getChannelGenerator(String channelName) { return channelGenerators.get(channelName); } public void setChannelGenerators(HashMap<String, ChannelGenerator> channelGenerators) { this.channelGenerators = channelGenerators; for (ChannelGenerator g: channelGenerators.values()) { for (IdentifierTemplate id: g.getIdentifierTemplates()) { identifierTemplates.put(id.getResourceName(), id); } } } public void addChannelGenerator(ChannelGenerator channelGenerator) { channelGenerators.put(channelGenerator.getChannelName(), channelGenerator); for (IdentifierTemplate id: channelGenerator.getIdentifierTemplates()) { identifierTemplates.put(id.getResourceName(), id); } } public Collection<ChannelGenerator> getIOChannelGenerators() { return ioChannelGenerators.values(); } public void setIOChannelGenerators(HashMap<String, ChannelGenerator> ioChannelGenerators) { this.ioChannelGenerators = ioChannelGenerators; for (ChannelGenerator g: ioChannelGenerators.values()) { for (IdentifierTemplate id: g.getIdentifierTemplates()) { identifierTemplates.put(id.getResourceName(), id); } } } public void addIOChannelGenerator(ChannelGenerator ioChannelGenerator) { ioChannelGenerators.put(ioChannelGenerator.getChannelName(), ioChannelGenerator); for (IdentifierTemplate id: ioChannelGenerator.getIdentifierTemplates()) { identifierTemplates.put(id.getResourceName(), id); } } public void addType(Type type) { types.put(type.getTypeName(), type); } public Type getType(String name) { return types.get(name); } public void addSymbol(Symbol symbol) { symbols.put(symbol.getName(), symbol); } public Symbol getSymbol(String name) { return symbols.get(name); } public static String getWrapperType(Type type) { if (type == typeInt) { return "Integer"; } else if (type == typeLong) { return "Long"; } else if (type == typeFloat) { return "Float"; } else if (type == typeDouble) { return "Double"; } else if (type == typeBoolean) { return "Boolean"; } return null; } public static boolean isListType(Type type) { return typeList.isAncestorOf(type); } @Override public String toString() { String out = ""; for (ChannelGenerator channelGenerator: ioChannelGenerators.values()) { out += channelGenerator.toString(); } for (ChannelGenerator channelGenerator: channelGenerators.values()) { out += channelGenerator.toString(); } return out; } }