]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Add fixes for foo^-bar expresisons and value arrays into vensim import
authorjkauttio <jkauttio@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Mon, 16 Jun 2014 13:02:51 +0000 (13:02 +0000)
committerjkauttio <jkauttio@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Mon, 16 Jun 2014 13:02:51 +0000 (13:02 +0000)
refs #2924

git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@29619 ac1ea38d-2e2b-0410-8846-a27921b304fc

org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/MdlParser.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/MdlUtil.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/mdl/MdlVariable.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/mdl/SketchVariable.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/mdl/SubscriptVariable.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Model.java

index bd23088e94dc2cd93b858f4b282f319a657f47e0..5fd3518205689783026067b6dd7d7e06b5f01f98 100644 (file)
@@ -89,7 +89,7 @@ public class MdlParser {
                                Valve symbol = valve.getSymbol();\r
                                if (symbol != null) {\r
                                        valve.setModelObject(symbol);\r
-                                       model.addSymbol(symbol);\r
+                                       model.addVariable(symbol);\r
                                }\r
                        }\r
                        \r
@@ -97,7 +97,7 @@ public class MdlParser {
                                Variable symbol = variable.getSymbol();\r
                                if (symbol != null) {\r
                                        variable.setModelObject(symbol);\r
-                                       model.addSymbol(symbol);\r
+                                       model.addVariable(symbol);\r
                                }\r
                        }\r
                        \r
@@ -108,10 +108,20 @@ public class MdlParser {
                for (Sketch sketch : mdl.getSketches()) {\r
                        for (SketchVariable variable : sketch.getShadowVariables()) {\r
                                Variable original = model.getVariable(variable.getName());\r
-                               Symbol symbol = original != null ? new Shadow(variable.getDimensions(), original) : variable.getSymbol();\r
-                               if (symbol != null) {\r
+                               if (original != null) {\r
+                                       // create a shadow variable if the original variable exists\r
+                                       Shadow symbol = new Shadow(variable.getDimensions(), original);\r
                                        variable.setModelObject(symbol);\r
-                                       model.addSymbol(symbol);\r
+                                       model.addShadow(symbol);\r
+                               }\r
+                               else {\r
+                                       // create a new original variable instead of a shadow variable if\r
+                                       // the original variable does not exist\r
+                                       Variable symbol = variable.getSymbol();\r
+                                       if (symbol != null) {\r
+                                               variable.setModelObject(symbol);\r
+                                               model.addVariable(symbol);\r
+                                       }\r
                                }\r
                        }\r
 \r
@@ -127,22 +137,22 @@ public class MdlParser {
                // Set simulation parameters\r
                MdlVariable start = mdl.getVariable(PARAMETER_START);\r
                if (start != null && Pattern.matches(MdlUtil.DBL, start.getExpressionString()))\r
-                       model.setStart(Double.parseDouble(start.getExpressionString()));\r
+                       model.setStartTime(Double.parseDouble(start.getExpressionString()));\r
                \r
                MdlVariable stop = mdl.getVariable(PARAMETER_STOP);\r
                if (stop != null && Pattern.matches(MdlUtil.DBL, stop.getExpressionString()))\r
-                       model.setStop(Double.parseDouble(stop.getExpressionString()));\r
+                       model.setStopTime(Double.parseDouble(stop.getExpressionString()));\r
                \r
                MdlVariable step = mdl.getVariable(PARAMETER_STEP);\r
                if (step != null && Pattern.matches(MdlUtil.DBL, step.getExpressionString())) {\r
-                       model.setStep(Double.parseDouble(step.getExpressionString()));\r
+                       model.setTimeStep(Double.parseDouble(step.getExpressionString()));\r
                        // TODO: for some reason sysdyn only accepts certain time units\r
                        // so this most definitely does not work in all cases\r
                        String unit = step.getUnit();\r
                        if (unit.contains("[")) {\r
                                unit = unit.substring(0, unit.indexOf('[')).trim();\r
                        }\r
-                       model.setUnit(unit.toLowerCase());\r
+                       model.setTimeUnit(unit.toLowerCase());\r
                }\r
                \r
                \r
index 2b80696b40822eef748535889ef08f343d967125..ceef806803dcdf8024cb645e47d09f1458b5fb8a 100644 (file)
@@ -1,6 +1,5 @@
 package org.simantics.sysdyn.modelImport;\r
 \r
-import java.util.ArrayList;\r
 import java.util.List;\r
 import java.util.regex.Matcher;\r
 import java.util.regex.Pattern;\r
@@ -59,8 +58,12 @@ public class MdlUtil {
                str = str.replaceAll(":AND:", " and ");\r
                str = str.replaceAll(":OR:", " or ");\r
                \r
-               // NOTE: this might not be correct\r
-               str = str.replaceAll("=", "==");\r
+               // foo^-bar does not work in Modelica, it needs to be changed to foo^(-bar)\r
+               str = addParenthesesToExponents(str);\r
+               \r
+               // NOTE: something like this must be done to replace Vensim comparison \r
+               // "=" with Modelica comparison "==" but this solution breaks geq and leq\r
+               //str = str.replaceAll("=", "==");\r
 \r
                return str;\r
        }\r
@@ -93,7 +96,7 @@ public class MdlUtil {
                        }\r
                        else {\r
                                // in all other cases, manipulate variable names slightly to \r
-                               // make them conform to modelica syntax (the proper way to do \r
+                               // make them conform to Modelica syntax (the proper way to do \r
                                // this would be to simply quote problematic variable names \r
                                // but quoted variable names are currently broken in sysdyn so \r
                                // that is not an option)\r
@@ -156,6 +159,29 @@ public class MdlUtil {
 \r
                return result.toString();\r
        }\r
+       \r
+       private static String addParenthesesToExponents(String expression) {\r
+               if (!expression.contains("^")) {\r
+                       return expression;\r
+               }\r
+               \r
+               StringBuilder result = new StringBuilder();\r
+               int offset = 0;\r
+               \r
+               Matcher matcher = Pattern.compile("\\^\\s*-\\s*"+VARIABLE_EXPRESSION).matcher(expression);\r
+               while (matcher.find()) {\r
+                       result.append(expression.substring(offset, matcher.start()));\r
+                       \r
+                       result.append("^(-").append(matcher.group(1)).append(")");\r
+                       \r
+                       offset = matcher.end();\r
+               }\r
+               if (offset < expression.length()) {\r
+                       result.append(expression.substring(offset));\r
+               }\r
+\r
+               return result.toString();\r
+       }\r
 \r
        public static String finalize(String expression, MdlModel mdl) {\r
                expression = expandIterations(expression, mdl);\r
@@ -269,40 +295,6 @@ public class MdlUtil {
 \r
                return result.toString();\r
        }\r
-\r
-       public static String[] splitFunctionParameters(String str) {\r
-               ArrayList<String> list = new ArrayList<String>();\r
-\r
-               int i;\r
-               int last = 0;\r
-               int level = 0;\r
-               boolean comment = false;\r
-               boolean brackets = false;\r
-\r
-               for (i = 0; i < str.length(); i++) {\r
-                       char current = str.charAt(i);\r
-                       if (current == '"')\r
-                               // note that this does not currently support escaped quotation marks inside quoted variable names\r
-                               comment = !comment;\r
-                       else if (current == '[' && !comment)\r
-                               brackets = true;\r
-                       else if (current == ']' && !comment)\r
-                               brackets = false;\r
-                       else if (current == '(' && !comment && !brackets)\r
-                               level++;\r
-                       else if (current == ')' && !comment && !brackets)\r
-                               level--;\r
-                       else if (current == ',' && !comment && !brackets && level == 0) {\r
-                               list.add(str.substring(last, i).trim());\r
-                               last = i + 1;\r
-                       }\r
-               }\r
-               if (last < i) {\r
-                       list.add(str.substring(last, i).trim());\r
-               }\r
-\r
-               return list.toArray(new String[list.size()]);\r
-       }\r
        \r
        public static double[] getSysdynDimensions(int x, int y, int width, int height) {\r
                return new double[] {\r
index 6e45c926afb5eaafae9be634634c6a402b6a0824..ad63d0034f96aec58be9728a486850ceb1b8eaf2 100644 (file)
@@ -1,5 +1,6 @@
 package org.simantics.sysdyn.modelImport.mdl;\r
 \r
+import java.util.ArrayList;\r
 import java.util.regex.Matcher;\r
 import java.util.regex.Pattern;\r
 \r
@@ -69,7 +70,12 @@ public class MdlVariable extends Declaration {
        }\r
        \r
        public Expression getExpression() {\r
-               return parseExpression(MdlUtil.finalize(expression, getMdl()));\r
+               if (expression == null) {\r
+                       return null;\r
+               }\r
+               else {\r
+                       return parseExpression(MdlUtil.finalize(expression, getMdl()));\r
+               }\r
        }\r
        \r
        protected static Expression parseExpression(String expression) {\r
@@ -81,10 +87,10 @@ public class MdlVariable extends Declaration {
                        return new NormalExpression(expression);\r
                }\r
                \r
-               String function = matcher.group(1);\r
-               String[] parameters = MdlUtil.splitFunctionParameters(matcher.group(2));\r
+               String function = matcher.group(1).toUpperCase();\r
+               String[] parameters = splitFunctionParameters(matcher.group(2));\r
                \r
-               if (function.startsWith("INTEG")) {\r
+               if (function.equals("INTEG")) {\r
                        // an integral expression\r
                        if (parameters.length != 2) {\r
                                System.err.println("malformed integral expression: "+expression);\r
@@ -92,7 +98,16 @@ public class MdlVariable extends Declaration {
                        }\r
                        return new IntegralExpression(parameters[0], parameters[1]);\r
                }\r
-               else if (function.startsWith("DELAY N")) {\r
+               else if (function.equals("INITIAL")) {\r
+                       // as we do not have a proper replacement for Vensim "initial" \r
+                       // function in sysdyn, replace it with a stock with no flows\r
+                       if (parameters.length != 1) {\r
+                               System.err.println("malformed initial expression: "+expression);\r
+                               return null;\r
+                       }\r
+                       return new IntegralExpression("0", parameters[0]);\r
+               }\r
+               else if (function.equals("DELAY N")) {\r
                        // a delay expression\r
                        if (parameters.length != 4) {\r
                                System.err.println("malformed delay expression: "+expression);\r
@@ -100,21 +115,35 @@ public class MdlVariable extends Declaration {
                        }\r
                        return new DelayExpression(parameters[0], parameters[1], parameters[2], Integer.parseInt(parameters[3]));\r
                }\r
-               else if (function.startsWith("SMOOTHI")) {\r
+               else if (function.equals("SMOOTH3I")) {\r
+                       if (parameters.length != 3) {\r
+                               System.err.println("malformed smoothi expression: "+expression);\r
+                       }\r
+                       // what is the correct degree for smooth?\r
+                       return new DelayExpression(parameters[0], parameters[1], parameters[2], 3);\r
+               }\r
+               else if (function.equals("SMOOTH3")) {\r
+                       if (parameters.length != 2) {\r
+                               System.err.println("malformed smooth expression: "+expression);\r
+                       }\r
+                       // what is the correct degree and initial value for smooth?\r
+                       return new DelayExpression(parameters[0], parameters[1], parameters[0], 3);\r
+               }\r
+               else if (function.equals("SMOOTHI")) {\r
                        if (parameters.length != 3) {\r
                                System.err.println("malformed smoothi expression: "+expression);\r
                        }\r
                        // what is the correct degree for smooth?\r
                        return new DelayExpression(parameters[0], parameters[1], parameters[2], 1);\r
                }\r
-               else if (function.startsWith("SMOOTH")) {\r
+               else if (function.equals("SMOOTH")) {\r
                        if (parameters.length != 2) {\r
                                System.err.println("malformed smooth expression: "+expression);\r
                        }\r
                        // what is the correct degree and initial value for smooth?\r
                        return new DelayExpression(parameters[0], parameters[1], parameters[0], 1);\r
                }\r
-               else if (function.startsWith("GAME")) {\r
+               else if (function.equals("GAME")) {\r
                        // a game expression, currently treated as a normal expression\r
                        if (parameters.length != 1) {\r
                                System.err.println("malformed game expression: "+expression);\r
@@ -152,4 +181,38 @@ public class MdlVariable extends Declaration {
                        return null;\r
                }\r
        }\r
+       \r
+       private static String[] splitFunctionParameters(String str) {\r
+               ArrayList<String> list = new ArrayList<String>();\r
+\r
+               int i;\r
+               int last = 0;\r
+               int level = 0;\r
+               boolean comment = false;\r
+               boolean brackets = false;\r
+\r
+               for (i = 0; i < str.length(); i++) {\r
+                       char current = str.charAt(i);\r
+                       if (current == '"')\r
+                               // note that this does not currently support escaped quotation marks inside quoted variable names\r
+                               comment = !comment;\r
+                       else if (current == '[' && !comment)\r
+                               brackets = true;\r
+                       else if (current == ']' && !comment)\r
+                               brackets = false;\r
+                       else if (current == '(' && !comment && !brackets)\r
+                               level++;\r
+                       else if (current == ')' && !comment && !brackets)\r
+                               level--;\r
+                       else if (current == ',' && !comment && !brackets && level == 0) {\r
+                               list.add(str.substring(last, i).trim());\r
+                               last = i + 1;\r
+                       }\r
+               }\r
+               if (last < i) {\r
+                       list.add(str.substring(last, i).trim());\r
+               }\r
+\r
+               return list.toArray(new String[list.size()]);\r
+       }\r
 }\r
index 9bcbeba810edfa90666476da5c014f00482c74c6..48c7ab88b0c2d7365971d3466d8924de0b2b6ea5 100644 (file)
@@ -7,6 +7,7 @@ import org.simantics.sysdyn.modelImport.MdlUtil;
 import org.simantics.sysdyn.modelImport.model.Auxiliary;\r
 import org.simantics.sysdyn.modelImport.model.Variable;\r
 import org.simantics.sysdyn.modelImport.model.Stock;\r
+import org.simantics.sysdyn.modelImport.model.expression.IntegralExpression;\r
 \r
 public class SketchVariable extends SketchElement {\r
        \r
@@ -50,8 +51,9 @@ public class SketchVariable extends SketchElement {
                }\r
                \r
                Variable var;\r
-               if (variable.getExpressionString() != null && variable.getExpressionString().startsWith("INTEG"))\r
+               if ((variable.getExpression() instanceof IntegralExpression)) {\r
                        var = new Stock();\r
+               }\r
                else\r
                        var = new Auxiliary();\r
                var.setDimensions(getDimensions());\r
index 2bbe092ba93eea1286c517447f7560fde9f21db1..ada64c8a6630e5d53268e7c32f8f59a70978abcc 100644 (file)
@@ -104,10 +104,7 @@ public class SubscriptVariable extends MdlVariable {
                        Subscript potential = getMdl().resolveSubscript(values);\r
                        if (potential == null) {\r
                                System.err.println("subscript indices could not be resolved ");\r
-                               for (String value : values) {\r
-                                       System.err.println("  "+value);\r
-                               }\r
-                               System.err.println();\r
+                               return null;\r
                        }\r
                        enumerations.add(potential.getEnumeration());\r
                }\r
@@ -116,14 +113,29 @@ public class SubscriptVariable extends MdlVariable {
                \r
                // populate the created expression\r
                \r
-               // TODO: is this check correct?\r
-               if (next == null && enumerations.size() == 2) {\r
-                       double[][] values = getPossibleValueArray(getExpressionString());\r
-                       if (values != null) {\r
+               // first check if the expression is just a (either one or two \r
+               // dimensional) list of values and just parse it if this is\r
+               // the case (should only happen if there is only one expression)\r
+               \r
+               if (next == null) {\r
+                       // number(,number)*\r
+                       if (enumerations.size() == 1 && \r
+                                       Pattern.matches(MdlUtil.DBL+"(,"+MdlUtil.DBL+")*", getExpressionString())) {\r
+                               String[] values = getExpressionString().split(",");\r
                                for (int i = 0; i < values.length; i++) {\r
-                                       for (int j = 0; j < values[i].length; j++) {\r
-                                               expr.addExpression(\r
-                                                               new NormalExpression(Double.toString(values[i][j])),\r
+                                       expr.addExpression(new NormalExpression(values[i]),\r
+                                                       enumerations.get(0).getValues().get(i));\r
+                               }\r
+                               return expr;\r
+                       }\r
+                       // (number(,number)*;)*\r
+                       else if (enumerations.size() == 2 && \r
+                                       Pattern.matches("("+MdlUtil.DBL+"(,"+MdlUtil.DBL+")*;)*", getExpressionString())) {\r
+                               String[] rows = getExpressionString().split(";");\r
+                               for (int i = 0; i < rows.length; i++) {\r
+                                       String[] values = rows[i].split(",");\r
+                                       for (int j = 0; j < values.length; j++) {\r
+                                               expr.addExpression(new NormalExpression(values[j]),\r
                                                                enumerations.get(0).getValues().get(i),\r
                                                                enumerations.get(1).getValues().get(j));\r
                                        }\r
@@ -183,29 +195,6 @@ public class SubscriptVariable extends MdlVariable {
                }\r
        }\r
        \r
-       private static double[][] getPossibleValueArray(String expression) {\r
-               // (number(,number)*;)*\r
-               Matcher matcher = Pattern.compile(\r
-                       "("+MdlUtil.DBL+"(,"+MdlUtil.DBL+")*;)*"\r
-                               ).matcher(expression);\r
-               \r
-               if (!matcher.matches()) {\r
-                       return null;\r
-               }\r
-               \r
-               String[] rows = expression.split(";");\r
-               double[][] result = new double[rows.length][];\r
-               for (int i = 0; i < rows.length; i++) {\r
-                       String[] columns = rows[i].split(",");\r
-                       result[i] = new double[columns.length];\r
-                       for (int j = 0; j < columns.length; j++) {\r
-                               result[i][j] = Double.parseDouble(columns[j]);\r
-                       }       \r
-               }\r
-               \r
-               return result;\r
-       }\r
-       \r
        private static String removeComparisons(String expression, String[] subscripts, String[] values) {\r
                \r
                if (!expression.contains("=")) {\r
index 61e663ead72807f5bea6f26402eb4b5cbb16b00f..14a82c8083acb06f5cc8b4f0d60bdd77cbf56bbf 100644 (file)
@@ -20,6 +20,7 @@ import java.util.Map;
 import org.simantics.databoard.Bindings;\r
 import org.simantics.db.Resource;\r
 import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.utils.NameUtils;\r
 import org.simantics.db.exception.DatabaseException;\r
 import org.simantics.diagram.stubs.DiagramResource;\r
 import org.simantics.layer0.Layer0;\r
@@ -60,39 +61,39 @@ public class Model implements IWriteableObject {
                connections = new ArrayList<Connection>();\r
        }\r
 \r
-       public double getStart() {\r
+       public double getStartTime() {\r
                return start;\r
        }\r
 \r
-       public void setStart(double start) {\r
+       public void setStartTime(double start) {\r
                this.start = start;\r
        }\r
 \r
-       public double getStop() {\r
+       public double getStopTime() {\r
                return stop;\r
        }\r
 \r
-       public void setStop(double stop) {\r
+       public void setStopTime(double stop) {\r
                this.stop = stop;\r
        }\r
 \r
-       public double getStep() {\r
+       public double getTimeStep() {\r
                return step;\r
        }\r
 \r
-       public void setStep(double step) {\r
+       public void setTimeStep(double step) {\r
                this.step = step;\r
        }\r
        \r
-       public String getUnit() {\r
+       public String getTimeUnit() {\r
                return unit;\r
        }\r
        \r
-       public void setUnit(String unit) {\r
+       public void setTimeUnit(String unit) {\r
                this.unit = unit;\r
        }\r
        \r
-       public void addSymbol(Variable variable) {\r
+       public void addVariable(Variable variable) {\r
                if (variables.get(variable.getName()) != null) {\r
                        System.err.println("variable "+variable.getName()+" already defined");\r
                        return;\r
@@ -111,7 +112,7 @@ public class Model implements IWriteableObject {
                return variables.values();\r
        }\r
        \r
-       public void addSymbol(Shadow shadow) {\r
+       public void addShadow(Shadow shadow) {\r
                shadows.add(shadow);\r
        }\r
                \r
@@ -165,7 +166,11 @@ public class Model implements IWriteableObject {
                SysdynResource sr = SysdynResource.getInstance(graph);\r
                \r
                model = ModelUtils.createModel(graph);\r
-               graph.claimLiteral(model, l0.HasLabel, name, Bindings.STRING);\r
+               \r
+               Resource container = graph.getSingleObject(model, l0.PartOf);\r
+               String freshName = NameUtils.findFreshName(graph, name, container, l0.ConsistsOf, "%s%d");\r
+               graph.claimLiteral(model, l0.HasName, freshName, Bindings.STRING);\r
+               graph.claimLiteral(model, l0.HasLabel, freshName, Bindings.STRING);\r
                \r
                // TODO: this must be updated if/when simulation parameters are moved \r
                // from model to experiment\r