From: lempinen Date: Tue, 1 Mar 2011 14:04:18 +0000 (+0000) Subject: Enumeration support X-Git-Tag: 2011-04-05-db-merge-trunk~9 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=f202105bcdc7c6afa48f96f52df40f4fc8353eae;p=simantics%2Fsysdyn.git Enumeration support git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@19859 ac1ea38d-2e2b-0410-8846-a27921b304fc --- diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/StockExpression.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/StockExpression.java index c58aa272..f07b19fb 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/StockExpression.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/StockExpression.java @@ -167,6 +167,7 @@ public class StockExpression implements IExpression { private String getIntegral(final Resource expression) { + String integral = ""; if(expression == null) return integral; @@ -189,14 +190,17 @@ public class StockExpression implements IExpression { Stock stock = (Stock)model.getElement(variable); + String range = graph.getPossibleRelatedValue(expression, sr.HasArrayRange); + if(range == null) + range = ""; StringBuilder builder = new StringBuilder(); builder.append(""); for(Valve in : stock.getIncomingValves()) { - builder.append(" + " + in.getName()); + builder.append(" + " + in.getName() + range); } for(Valve out : stock.getOutgoingValves()) { - builder.append(" - " + out.getName()); + builder.append(" - " + out.getName() + range); } if (builder.indexOf(" + ") == 0) builder.delete(0, 3); diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ExpressionUtils.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ExpressionUtils.java index 2caf1d20..180b2fc5 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ExpressionUtils.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ExpressionUtils.java @@ -278,6 +278,7 @@ public class ExpressionUtils { boolean isFound = false; Enumeration e = (Enumeration)v; + // TODO: add .elements and .size if(enumeration.equals(et.image)) { // The full enumeration isFound = true; diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/viewUtils/SysdynDatasetSelectionListener.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/viewUtils/SysdynDatasetSelectionListener.java index 4425ce9c..38e7b92c 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/viewUtils/SysdynDatasetSelectionListener.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/viewUtils/SysdynDatasetSelectionListener.java @@ -26,6 +26,7 @@ import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.Session; +import org.simantics.db.common.request.ObjectsWithType; import org.simantics.db.common.request.ReadRequest; import org.simantics.db.common.utils.OrderedSetUtils; import org.simantics.db.exception.DatabaseException; @@ -161,6 +162,8 @@ public abstract class SysdynDatasetSelectionListener implements ISelectionListen rvis.put(rvi, rvi); } else { List arrayIndexList= OrderedSetUtils.toList(g, arrayIndexes); + resolveActiveArrayIndexes(g, variable, arrayIndexList); + if(arrayIndexList.size() > 0) traverseIndexes(g, rvi, rvis, arrayIndexList); else @@ -187,6 +190,40 @@ public abstract class SysdynDatasetSelectionListener implements ISelectionListen } + private static List resolveActiveArrayIndexes(ReadGraph graph, Variable variable, List enumerations) { + try { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + String uri = variable.getURI(graph); + uri = uri.substring(0, uri.lastIndexOf("/")); + Variable v = Variables.getPossibleVariable(graph, uri); + if(v != null) { + RepresentsProperty rp = (RepresentsProperty)v.getProperty(graph, Variables.REPRESENTS); + Resource module = rp.getValue(graph); + if(module != null && graph.isInheritedFrom(graph.getSingleObject(module, l0.InstanceOf), sr.Module)) { + + boolean somethingIsReplaced = false; + for(Resource redeclaration : graph.syncRequest(new ObjectsWithType(module, sr.HasRedeclaration, sr.Redeclaration))) { + Resource replaced = graph.getSingleObject(redeclaration, sr.ReplacedEnumeration); + if(enumerations.contains(replaced)) { + enumerations.add(enumerations.indexOf(replaced), graph.getSingleObject(redeclaration, sr.ReplacingEnumeration)); + enumerations.remove(replaced); + somethingIsReplaced = true; + } + } + + if(somethingIsReplaced) { + resolveActiveArrayIndexes(graph, v, enumerations); + } + } + } + } catch (DatabaseException e) { + e.printStackTrace(); + + } + return enumerations; + } + private void traverseIndexes(ReadGraph g, String rvi, HashMap rvis, List arrayIndexes) throws DatabaseException { traverseIndexes(g, rvi, rvis, arrayIndexes, arrayIndexes.get(0), "", ""); } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/ExpressionParser.jj b/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/ExpressionParser.jj index 567a9e46..57cbe036 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/ExpressionParser.jj +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/expressionParser/ExpressionParser.jj @@ -15,8 +15,21 @@ import java.util.HashMap; public class ExpressionParser { + public class ForRange { public Token start; + public Token end; + } + boolean forIndex = false; + Token firstToken; + public Token getFirstToken() { return firstToken; + } + List forRanges = new ArrayList(); + + public List getForRanges() { + return forRanges; + } + HashMap> references = new HashMap>(); public HashMap> getReferences() { @@ -94,11 +107,17 @@ TOKEN: // { add_op term } -> ( add_op() term() )* void expr() : { - references = new HashMap>(); } { - simple_expression() - | "if" expression() "then" expression() ( "elseif" expression() "then" expression() )* - "else" expression() + { + firstToken = token; + } + simple_expression() + | + { + firstToken = token; + } + "if" expression() "then" expression() ( "elseif" expression() "then" expression() )* + "else" expression() } void expression() : { @@ -242,7 +261,14 @@ void for_index() : { { forIndices.put(token, currentRange); forIndex = true; } - ( "in" expression() )? + ( "in" { + ForRange forRange = new ForRange(); + forRange.start = token; } + expression() { + forRange.start = forRange.start.next; + forRange.end = token; + forRanges.add(forRange); } + )? { forIndex = false; } } @@ -282,7 +308,7 @@ void array_subscripts() : { if(ranges.get(token.image) == null) { void subscript(List currentRange) : { Token rangeToken = new Token(token.kind, ""); - rangeToken.beginColumn = token.beginColumn; + rangeToken.beginColumn = token.beginColumn + 1; rangeToken.beginLine = token.beginLine; } { ":" { currentRange.add(token); } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/MdlParser.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/MdlParser.java index dd73915f..66f44e26 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/MdlParser.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/MdlParser.java @@ -27,6 +27,7 @@ import org.simantics.sysdyn.mdlImport.mdlElements.Cloud; import org.simantics.sysdyn.mdlImport.mdlElements.Connection; import org.simantics.sysdyn.mdlImport.mdlElements.Dependency; import org.simantics.sysdyn.mdlImport.mdlElements.Element; +import org.simantics.sysdyn.mdlImport.mdlElements.EquivalenceSubscript; import org.simantics.sysdyn.mdlImport.mdlElements.Expression; import org.simantics.sysdyn.mdlImport.mdlElements.Flow; import org.simantics.sysdyn.mdlImport.mdlElements.Model; @@ -81,10 +82,13 @@ public class MdlParser { input.reset(); } + + boolean isControl = false; + while (( line = input.readLine()) != null){ // Build an element (combine the lines to one string) StringBuilder elementBuilder = new StringBuilder(); - while(line != null) { + while(line != null && !line.contains("\\\\\\---///")) { // Add a new line for the element elementBuilder.append(line); if(line.endsWith("|") && !line.endsWith("~~|")) { @@ -94,36 +98,28 @@ public class MdlParser { line = input.readLine(); } - String variable = elementBuilder.toString(); - if(variable.contains(".Control")) { - // Start of control variables + if(line.contains("\\\\\\---///")) break; - } else { - // Add element string to model - mdlFile.addVariable(variable); - } - } - - while (( line = input.readLine()) != null && !line.contains("\\\\\\---///")){ - if(line.trim().isEmpty()) - continue; - // Build a control element (combine the lines to one string) - StringBuilder elementBuilder = new StringBuilder(); - while(line != null) { - // Add a new line for the element - elementBuilder.append(line); - if(line.endsWith("|") && !line.endsWith("~~|")) { - //Element definition has ended - break; + String variable = elementBuilder.toString(); + + if(variable.trim().matches("[\\*]{46}.+[\\*]{46}.+")) { + if(variable.contains(".Control")) { + isControl = true; + } else { + isControl = false; } - line = input.readLine(); + continue; + } + + // Add element string to model + if(isControl) { + mdlFile.addControl(variable); + } else { + mdlFile.addVariable(variable); } - String control = elementBuilder.toString(); - mdlFile.addControl(control); } - while (( line = input.readLine()) != null && !line.contains("///---\\\\\\")){ mdlFile.addSketchData(line); } @@ -144,9 +140,21 @@ public class MdlParser { } private static void getVariableData(Model model, ArrayList elements) { - for(String elementString : elements) { - createVariable(model, elementString); + ArrayList equivalenceSubscripts = new ArrayList(); + for(String elementString : elements) { + Variable v = createVariable(model, elementString); + if(v instanceof EquivalenceSubscript){ + equivalenceSubscripts.add((EquivalenceSubscript) v); + } + } + + // All variables are ready, determine subscript equivalences + for(EquivalenceSubscript es : equivalenceSubscripts) { + Element e = model.getElement(es.getEquivalentToName()); + if(e != null && e instanceof Subscript) { + es.setEquivalentTo((Subscript)e); } + } } @@ -169,6 +177,55 @@ public class MdlParser { } + private static Variable getVariable(Model model, String name) { + Element e = model.getElement(name); + Variable variable = null; + if(e != null && e instanceof Variable) + variable = (Variable)e; + return variable; + } + + private static String[] getNormalVariableNameDataAndRange(String element) { + String[] nameAndData = element.split("=", 2); + String[] nameAndRange = nameAndData[0].trim().split("[\\[|\\]]"); + if(nameAndData.length == 2) + return new String[] {nameAndRange[0], nameAndData[1], nameAndRange.length == 2 ? nameAndRange[1] : null}; + return null; + } + + private static String[] getSubscriptNameAndData(String element) { + String[] nameAndData = element.split(":"); + if(nameAndData.length == 2) + return nameAndData; + return null; + } + + private static String[] getEquivalenceSubscriptNameAndData(String element) { + String[] nameAndData = element.split("\\<\\-\\>"); + if(nameAndData.length == 2) + return nameAndData; + return null; + } + + private static String[] getTableNameDataAndRange(String element) { + String[] parts = element.split("\\~"); + if(!parts[0].contains("(") || !parts[0].contains(")")) + return null; + String name = element.substring(0, element.indexOf("(")); + String theRest = element.substring(element.indexOf("(")); + String[] nameAndData = {name, theRest}; + String[] nameAndRange = nameAndData[0].trim().split("[\\[|\\]]"); + if(nameAndData.length == 2) + return new String[] {nameAndRange[0], nameAndData[1], nameAndRange.length == 2 ? nameAndRange[1] : null}; + return nameAndData; + } + + private static String[] getDataVariableNameAndData(String element) { + String[] nameAndData = { + element.substring(0, element.indexOf("~")), + " " + element.substring(element.indexOf("~"))}; + return nameAndData; + } private static Variable createVariable(Model model, String elementString) { @@ -182,106 +239,132 @@ public class MdlParser { continue; Expression expression = new Expression(); - String[] nameAndData = s.split("=", 2); - if(nameAndData.length == 2) { - // A normal variable of some sort - String[] nameAndRange = nameAndData[0].trim().split("[\\[|\\]]"); + + String[] nameAndData = null; + String name; + + // Create the expression based on the expression string + if((nameAndData = getNormalVariableNameDataAndRange(s)) != null) { - // Get element in the first iteration + name = nameAndData[0].replace("\"", ""); + variable = getVariable(model, name); if(variable == null) { - Element e = model.getElement(nameAndRange[0]); - if(e != null && e instanceof Variable) - variable = (Variable)e; - if(variable == null) { - variable = new Auxiliary(); - variable.setName(nameAndRange[0].replace("\"", "")); - model.addElement(variable); - } + variable = new Auxiliary(); + variable.setName(name); + model.addElement(variable); } - - if(nameAndRange.length == 2) - expression.setRange(nameAndRange[1]); - if(!nameAndData[1].trim().endsWith("|")) { // Multiple expressions expression.setExpression(nameAndData[1].trim()); } else { String[] expressionUnitsAndComments = nameAndData[1].split("[\\~|\\|]"); expression.setExpression(expressionUnitsAndComments[0].trim()); - - expressionUnitsAndComments[1] = expressionUnitsAndComments[1].trim(); - - if(expressionUnitsAndComments[1].contains("[") && - expressionUnitsAndComments[1].contains("]") && - expressionUnitsAndComments[1].lastIndexOf("]") == expressionUnitsAndComments[1].length() - 1) { - // Range definitions are at the end - String range = expressionUnitsAndComments[1].substring( - expressionUnitsAndComments[1].lastIndexOf("[") + 1, - expressionUnitsAndComments[1].length() - 1); - String[] rangeParts = range.split(","); - - try { - variable.setRangeStart(Double.parseDouble(rangeParts[0])); - if(rangeParts.length >= 2) - variable.setRangeEnd(Double.parseDouble(rangeParts[1])); - if(rangeParts.length >= 3) - variable.setRangeStep(Double.parseDouble(rangeParts[2])); - } catch (NumberFormatException e) { - // Not a double - } - expressionUnitsAndComments[1] = expressionUnitsAndComments[1].substring(0, expressionUnitsAndComments[1].lastIndexOf("[")); - } - variable.setUnits(expressionUnitsAndComments[1].trim()); - - - variable.setComments(expressionUnitsAndComments[2].trim()); } - } else { - // SUBSCRIPT - String[] subscript = s.split(":"); - if(subscript.length == 2) { - // Subscript + + } else if((nameAndData = getSubscriptNameAndData(s)) != null) { + + name = nameAndData[0].replace("\"", ""); + variable = getVariable(model, name); + if(variable == null) { variable = new Subscript(); + variable.setName(name); model.addElement(variable); - variable.setName(subscript[0].replace("\"", "")); - String[] expressionUnitsAndComments = subscript[1].split("[\\~|\\|]"); - expression.setExpression(expressionUnitsAndComments[0].trim()); - variable.setUnits(expressionUnitsAndComments[1].trim()); - variable.setComments(expressionUnitsAndComments[2].trim()); - } else if(s.contains("(")){ - // TABLE: These are actually functions in vensim. When function library is created, use these to create interpolation functions + } + + // No support for multidimensional variables. Don't know what that would mean + String[] expressionUnitsAndComments = nameAndData[1].split("[\\~|\\|]"); + expression.setExpression(expressionUnitsAndComments[0].trim()); + variable.setUnits(expressionUnitsAndComments[1].trim()); + variable.setComments(expressionUnitsAndComments[2].trim()); + + } else if((nameAndData = getEquivalenceSubscriptNameAndData(s)) != null) { + + name = nameAndData[0].replace("\"", ""); + variable = getVariable(model, name); + if(variable == null) { + variable = new EquivalenceSubscript(); + variable.setName(name); + model.addElement(variable); + } + + // No support for multidimensional variables. Don't know what that would mean + String[] expressionUnitsAndComments = nameAndData[1].split("[\\~|\\|]"); + expression.setExpression(expressionUnitsAndComments[0].trim()); + variable.setUnits(expressionUnitsAndComments[1].trim()); + variable.setComments(expressionUnitsAndComments[2].trim()); + + } else if((nameAndData = getTableNameDataAndRange(s)) != null) { + + name =(nameAndData[0].replace("\"", "")); + variable = getVariable(model, name); + if(variable == null) { variable = new Auxiliary(); - variable.setName(s.substring(0, s.indexOf("(")).replace("\"", "")); + variable.setName(name); model.addElement(variable); - String theRest = s.substring(s.indexOf("(") + 1); - String[] expressionUnitsAndComments = theRest.split("[\\~|\\|]"); - variable.setUnits(expressionUnitsAndComments[1].trim()); - variable.setComments(expressionUnitsAndComments[2].trim()); - // [(0,0)-(2,5)],(0,5),(0.5,3),(1,0.5),(2,0.5) => ,(0,5),(0.5,3),(1,0.5),(2,0.5) - String table = expressionUnitsAndComments[0].trim().split("[\\[|\\]]")[2]; - // ,(0,5),(0.5,3),(1,0.5),(2,0.5) => (0,5),(0.5,3),(1,0.5),(2,0.5) - table = table.substring(table.indexOf(",") + 1, table.lastIndexOf(")")); - table = "{" + table + "}"; - table = table.replace("(", "{"); - table = table.replace(")", "}"); - expression.setExpression(table); - } else { - // Just an empty variable, Data-driven variable + } + + String[] expressionUnitsAndComments = nameAndData[1].split("[\\~|\\|]"); + // ([(0,0)-(2,5)],(0,5),(0.5,3),(1,0.5),(2,0.5) => ( ; (0,0)-(2,5) ; ,(0,5),(0.5,3),(1,0.5),(2,0.5) + String table = expressionUnitsAndComments[0].trim().split("[\\[|\\]]")[2]; + // ,(0,5),(0.5,3),(1,0.5),(2,0.5) => (0,5),(0.5,3),(1,0.5),(2,0.5) + table = table.substring(table.indexOf(",") + 1, table.lastIndexOf(")")); + table = "{" + table + "}"; + table = table.replace("(", "{"); + table = table.replace(")", "}"); + expression.setExpression(table); + + + } else if((nameAndData = getDataVariableNameAndData(s)) != null) { + + name = nameAndData[0].replace("\"", ""); + variable = getVariable(model, name); + if(variable == null) { variable = new Auxiliary(); - String[] nameUnitsAndComments = s.split("[\\~|\\|]"); - variable.setName(nameUnitsAndComments[0].trim().replace("\"", "")); + variable.setName(name); model.addElement(variable); - expression.setExpression(""); - variable.setUnits(nameUnitsAndComments[1].trim()); - variable.setComments(nameUnitsAndComments[2].trim()); } - } + + expression.setExpression(""); + } + + if(nameAndData == null || variable == null) + continue; + + // Set possible range for the expression + if(nameAndData.length == 3) + expression.setRange(nameAndData[2]); - if(variable != null) { - // Finally add the expression to element - variable.getExpressions().add(expression); + // Set units and comments for the variable + if(nameAndData[1].trim().endsWith("|")) { + String[] expressionUnitsAndComments = nameAndData[1].split("[\\~|\\|]"); + String units = expressionUnitsAndComments[1].trim(); + if(units.contains("[") && + units.contains("]") && + units.lastIndexOf("]") == units.length() - 1) { + // Range definitions are at the end + String range = units.substring( + units.lastIndexOf("[") + 1, + units.length() - 1); + String[] rangeParts = range.split(","); + + try { + variable.setRangeStart(Double.parseDouble(rangeParts[0])); + if(rangeParts.length >= 2) + variable.setRangeEnd(Double.parseDouble(rangeParts[1])); + if(rangeParts.length >= 3) + variable.setRangeStep(Double.parseDouble(rangeParts[2])); + } catch (NumberFormatException e) { + // Not a double + } + expressionUnitsAndComments[1] = units.substring(0, units.lastIndexOf("[")); + } + variable.setUnits(expressionUnitsAndComments[1].trim()); + variable.setComments(expressionUnitsAndComments[2].trim()); } + + // Finally add the expression to element + variable.getExpressions().add(expression); } return variable; } @@ -322,7 +405,7 @@ public class MdlParser { String[] data = line.split(","); if(data[0].equals("1")) { // Connections are handled after all elements - String[] connectionData = line.split("[,\\|\\(\\)]"); + String[] connectionData = line.split(","); connections.add(connectionData); } else if(data[0].equals("11")){ @@ -376,6 +459,7 @@ public class MdlParser { model.addElement(view, e); } } + e.setX(Integer.parseInt(data[3]) / SCALE); e.setY(Integer.parseInt(data[4]) / SCALE); elementNumbers.put(data[1], e); @@ -433,9 +517,9 @@ public class MdlParser { // Dependency Point2D startPoint = new Point2D.Double(start.getX(), start.getY()); Point2D endPoint = new Point2D.Double(end.getX(), end.getY()); - Double controlX = Double.parseDouble(connectionData[15]) / SCALE; - Double controlY = Double.parseDouble(connectionData[16]) / SCALE; - Point2D controlPoint = new Point2D.Double(controlX, controlY); + String controlX = connectionData[13].substring(connectionData[13].indexOf("(") + 1); + String controlY = connectionData[14].substring(0, connectionData[14].indexOf(")")); + Point2D controlPoint = new Point2D.Double(Double.parseDouble(controlX) / SCALE, Double.parseDouble(controlY) / SCALE); if(ghostNumbers.contains(connectionData[2]) || ghostNumbers.contains(connectionData[3])) { diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/EquivalenceSubscript.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/EquivalenceSubscript.java new file mode 100644 index 00000000..74741b30 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/EquivalenceSubscript.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.mdlImport.mdlElements; + +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; + +public class EquivalenceSubscript extends Subscript { + + public String getEquivalentToName() { + String name = ""; + if(expressions != null && expressions.get(0) != null) { + name = expressions.get(0).getExpression().trim(); + } + return name; + } + + public void setEquivalentTo(Subscript equivalentTo) { + setExpressions(equivalentTo.getExpressions()); + } + + @Override + public void write(WriteGraph graph, Resource parent, double xOffset, + double yOffset) { + super.write(graph, parent, xOffset, yOffset); + } + +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Stock.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Stock.java index fdb90541..e3437f38 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Stock.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Stock.java @@ -23,10 +23,11 @@ public class Stock extends Variable { @Override public Resource getExpression(WriteGraph graph, Expression expression) throws DatabaseException { + String integralEquation = ImportUtils.escapeExpression(getIntegralParts(expression)[1]); SysdynResource sr = SysdynResource.getInstance(graph); Resource e = GraphUtils.create2(graph, sr.StockExpression, - sr.HasInitialEquation, ImportUtils.escapeExpression(getIntegralParts(expression)[1])); + sr.HasInitialEquation, integralEquation); return e; } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Enumeration.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Enumeration.java index ebde6003..6a4a4807 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Enumeration.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Enumeration.java @@ -1,9 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ package org.simantics.sysdyn.representation; import java.util.ArrayList; import org.simantics.objmap.annotations.GraphType; import org.simantics.objmap.annotations.RelatedElement; +import org.simantics.objmap.annotations.RelatedElements; import org.simantics.objmap.annotations.RelatedValue; import org.simantics.sysdyn.representation.visitors.IElementVisitorVoid; @@ -15,6 +27,11 @@ public class Enumeration extends Variable { @RelatedValue("http://www.simantics.org/Sysdyn-1.0/IsReplaceable") private Boolean isReplaceable; + + @RelatedElements( + value = "http://www.simantics.org/Sysdyn-1.0/ReplacedEnumeration/Inverse", + composition = true) + private ArrayList redeclarations = new ArrayList(); @Override public void accept(IElementVisitorVoid v) { @@ -23,13 +40,10 @@ public class Enumeration extends Variable { public String getDeclaration() { StringBuilder sb = new StringBuilder(); + sb.append(getEnumerationClassDefinition()); sb.append(" "); - if(isReplaceable()) - sb.append("replaceable "); - sb.append(this.getType()); + sb.append(this.name + "_class"); sb.append(" " + this.name); - sb.append(" = "); - sb.append(getEnumerationDefinition()); sb.append(";\n"); return sb.toString(); } @@ -42,16 +56,37 @@ public class Enumeration extends Variable { return Boolean.TRUE.equals(isReplaceable); } - public String getEnumerationDefinition() { + public String getEnumerationClassDefinition() { StringBuilder sb = new StringBuilder(); - sb.append("enumeration("); - for(int i = 0; i < enumerationIndexes.getEnumerationIndexes().size(); i++) { - sb.append(enumerationIndexes.getEnumerationIndexes().get(i).getName()); - if(i < enumerationIndexes.getEnumerationIndexes().size() - 1) - sb.append(", "); + ArrayList indexes = getEnumerationIndexes(); + sb.append(" class "); + sb.append(this.name); + sb.append("_class\n parameter Integer size = "); + sb.append(indexes.size()); + sb.append(";\n"); + StringBuilder arrayBuilder = new StringBuilder(); + arrayBuilder.append("{"); + for(int i = 1; i <= indexes.size(); i++) { + sb.append(" constant Integer "); + sb.append(indexes.get(i - 1).getName()); + sb.append(" = " + i + ";\n"); + + arrayBuilder.append(i); + if(i < indexes.size()) + arrayBuilder.append(","); } - sb.append(")"); + arrayBuilder.append("}"); + sb.append(" constant Integer[" + indexes.size() + "] elements = "); + sb.append(arrayBuilder); + sb.append(";\n end "); + sb.append(this.name); + sb.append("_class;\n"); + return sb.toString(); } + + public ArrayList getRedeclarations() { + return redeclarations; + } } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java index 746685c3..fa6b9f59 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java @@ -15,7 +15,6 @@ import java.util.ArrayList; import org.simantics.sysdyn.representation.expressions.IExpression; import org.simantics.sysdyn.representation.expressions.ParameterExpression; -import org.simantics.sysdyn.representation.expressions.StockExpression; public abstract class IndependentVariable extends Variable { @@ -76,7 +75,7 @@ public abstract class IndependentVariable extends Variable { if(ai != null) enumerations = ai.getEnumerations(); IExpression firstExpression = expressions.get(0); - if(enumerations == null || enumerations.size() < 1 || firstExpression instanceof StockExpression) { + if(enumerations == null || enumerations.size() < 1) { // NOT an array variable, get equation from the only expression. if(firstExpression == null || firstExpression instanceof ParameterExpression) return null; diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Input.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Input.java index 8a2a543c..2c387726 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Input.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Input.java @@ -71,7 +71,7 @@ public class Input extends Variable { sb.append("["); Iterator iterator = enumerations.iterator(); while(iterator.hasNext()) { - sb.append(iterator.next().getName()); + sb.append(iterator.next().getName() + ".size"); if(iterator.hasNext()) { sb.append(", "); } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Redeclaration.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Redeclaration.java index 7cddf5a7..672713f4 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Redeclaration.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Redeclaration.java @@ -28,12 +28,22 @@ public class Redeclaration { return ""; } StringBuilder sb = new StringBuilder(); - sb.append("redeclare type "); sb.append(replacedEnumeration.getName()); - sb.append(" = "); - sb.append(replacingEnumeration.getEnumerationDefinition()); + sb.append(".size = "); + sb.append(replacingEnumeration.getName()); + sb.append(".size"); return sb.toString(); } + public Enumeration getReplacedEnumeration() { + return replacedEnumeration; + } + + public Enumeration getReplacingEnumeration() { + return replacingEnumeration; + } + + + } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/NormalExpression.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/NormalExpression.java index af48ccad..a528afae 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/NormalExpression.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/NormalExpression.java @@ -41,7 +41,7 @@ public class NormalExpression extends Expression { sb.append("["); Iterator iterator = enumerations.iterator(); while(iterator.hasNext()) { - sb.append(iterator.next().getName()); + sb.append(iterator.next().getName() + ".size"); if(iterator.hasNext()) { sb.append(", "); } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ParameterExpression.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ParameterExpression.java index 94d3c8a2..47a9c8d6 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ParameterExpression.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ParameterExpression.java @@ -43,7 +43,7 @@ public class ParameterExpression extends Expression { sb.append("["); Iterator iterator = enumerations.iterator(); while(iterator.hasNext()) { - sb.append(iterator.next().getName()); + sb.append(iterator.next().getName() + ".size"); if(iterator.hasNext()) { sb.append(", "); } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/StockExpression.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/StockExpression.java index 2212b1eb..620c8b51 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/StockExpression.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/StockExpression.java @@ -18,8 +18,8 @@ import org.simantics.objmap.annotations.GraphType; import org.simantics.objmap.annotations.RelatedValue; import org.simantics.sysdyn.representation.ArrayIndexes; import org.simantics.sysdyn.representation.Enumeration; -import org.simantics.sysdyn.representation.Stock; import org.simantics.sysdyn.representation.IndependentVariable; +import org.simantics.sysdyn.representation.Stock; import org.simantics.sysdyn.representation.Valve; import org.simantics.sysdyn.representation.utils.IndexUtils; @@ -44,7 +44,7 @@ public class StockExpression extends Expression { sb.append("["); Iterator iterator = enumerations.iterator(); while(iterator.hasNext()) { - sb.append(iterator.next().getName()); + sb.append(iterator.next().getName() + ".size"); if(iterator.hasNext()) { sb.append(", "); } @@ -53,57 +53,55 @@ public class StockExpression extends Expression { range = sb.toString(); } - String each = ""; - if( variable.getArrayIndexes() == null ||variable.getArrayIndexes().getEnumerations().isEmpty()) - each = ""; - else - each = "each"; + String each = variable.getArrayIndexes().getEnumerations().isEmpty() ? "" : "each"; if (value == null) { return " " + variable.getType() + " " + variable.getName() + range + "(" + each + " fixed=false);\n"; } else { return " " + variable.getType() + " " + variable.getName() + range + "(" + each+ " start=" + value + "," + each + " fixed=true);\n"; } - } @Override public String getEquation(IndependentVariable variable) { + String range = IndexUtils.rangeToIndexes(variable, this.getArrayRange()); StringBuilder b = new StringBuilder(); b.append(" der(") - .append(variable.getName()) + .append(variable.getName() + range) .append(") ="); for(Valve valve : ((Stock)variable).getIncomingValves()) - b.append("\n + ").append(valve.getName()); + b.append("\n + ").append(valve.getName() + range); for(Valve valve : ((Stock)variable).getOutgoingValves()) - b.append("\n - ").append(valve.getName()); + b.append("\n - ").append(valve.getName() + range); b.append(";\n"); return b.toString(); } @Override public String getInitialEquation(IndependentVariable variable) { - Double value = getStartValue(variable); - if (value != null) { - return null; - } else { - String range = IndexUtils.rangeToIndexes(variable, this.getArrayRange()); - return " " + variable.getName() + (range.equals("[:]") ? "" : range) + " = " + initialEquation + ";\n"; - } + try { + Double.parseDouble(initialEquation); + return null; + } catch (Exception e){ + // Has an initial equation + } + String range = IndexUtils.rangeToIndexes(variable, this.getArrayRange()); + if(range == null) + range = ""; + return " " + variable.getName() + range + " = " + initialEquation + ";\n"; + } private Double getStartValue(IndependentVariable variable) { - Double value = null; - try { - value = Double.parseDouble(initialEquation); - } catch (Exception e){ - // Has an initial equation - return null; - } - // Has initial equations if has multiple expressions - if(variable.getExpressions().getExpressions().size() > 1) - return null; - + Double value = null; + ArrayList expressions = variable.getExpressions().getExpressions(); + if(expressions.size() == 1) { + IExpression e = expressions.get(0); + if(e.getInitialEquation(variable) == null) { + // Has start value + value = Double.parseDouble(initialEquation); + } + } return value; } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/IndexUtils.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/IndexUtils.java index defd75cd..6c379a42 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/IndexUtils.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/IndexUtils.java @@ -1,8 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ package org.simantics.sysdyn.representation.utils; +import java.io.StringReader; import java.util.ArrayList; import java.util.StringTokenizer; +import org.simantics.sysdyn.expressionParser.ExpressionParser; +import org.simantics.sysdyn.expressionParser.ExpressionParser.ForRange; +import org.simantics.sysdyn.expressionParser.ParseException; import org.simantics.sysdyn.representation.ArrayIndexes; import org.simantics.sysdyn.representation.Configuration; import org.simantics.sysdyn.representation.Enumeration; @@ -54,6 +69,24 @@ public class IndexUtils { return sb.toString(); } + private static String fixForRangeEnumerations(Variable variable, String equation) { + ExpressionParser parser = new ExpressionParser(new StringReader(equation)); + try { + parser.expr(); + for(ForRange forRange : parser.getForRanges()) { + if(forRange.start.equals(forRange.end)) { + Variable v = getVariable(variable.getParentConfiguration(), forRange.start.image); + if(v instanceof Enumeration) { + equation = equation.replaceAll("in[\\s]*" + forRange.start.image + "($|[^\\.])", "in " + forRange.start.image + ".elements$1"); + } + } + } + } catch (ParseException e) { + e.printStackTrace(); + } + return equation; + } + public static String equationRangesToIndexes(Variable variable, String equation) { if(equation == null || !equation.contains("[")) return equation; @@ -81,7 +114,9 @@ public class IndexUtils { } prevToken = nextToken; } - return result.toString(); + + equation = fixForRangeEnumerations(variable, result.toString()); + return equation; } private static Variable getVariable(Configuration configuration, String name) {