]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Update vensim import, partial subscript support
authorjkauttio <jkauttio@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Mon, 31 Mar 2014 13:28:14 +0000 (13:28 +0000)
committerjkauttio <jkauttio@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Mon, 31 Mar 2014 13:28:14 +0000 (13:28 +0000)
refs #2924

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

dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/MdlParser2.java
dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/MdlUtils.java
dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Element2.java
dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Enumeration2.java [new file with mode: 0644]
dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/MdlModel.java
dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Model2.java
dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/ModelVariable.java
dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Subscript2.java [new file with mode: 0644]
dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SubscriptExpression.java [new file with mode: 0644]
dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Variable2.java

index aa667ca1da8b6c364193a671cd5610652965e37a..7b0b1cd14dc8af24e16ce4f4748a35c0509c0a0e 100644 (file)
@@ -36,18 +36,10 @@ import org.simantics.sysdyn.modelImport.model.SketchElement;
 import org.simantics.sysdyn.modelImport.model.SketchValve;\r
 import org.simantics.sysdyn.modelImport.model.SketchVariable;\r
 import org.simantics.sysdyn.modelImport.model.Stock2;\r
+import org.simantics.sysdyn.modelImport.model.Subscript2;\r
 import org.simantics.sysdyn.modelImport.model.Valve2;\r
 import org.simantics.sysdyn.modelImport.model.Variable2;\r
 \r
-/*\r
- * THINGS TO FIX:\r
- * - vensim apparently supports infix operators (:AND: instead of AND()), these must be handled\r
- * - "public" seems to be a keyboard of some sort which causes a problem in certain variable names\r
- * - something is seriously wrong with the sketch import\r
- * - how should models with multiple sketches be handled (this might already work)\r
- * - instead of splitting the file into blocks, the parser could already process the data further which would greatly simplify later methods\r
- */\r
-\r
 public class MdlParser2 {\r
 \r
        private static final String UTF_8 = "{UTF-8}";\r
@@ -84,6 +76,10 @@ public class MdlParser2 {
                HashMap<Variable2, Element2> variableToElement = new HashMap<Variable2, Element2>();\r
                ArrayList<SketchVariable> shadows = new ArrayList<SketchVariable>();\r
                \r
+               for (Subscript2 ss : mdl.getSubscripts()) {\r
+                       System.err.println("SUBSCRIPT "+ss.getName()+": "+ss.getValues());\r
+               }\r
+               \r
                // add sketch labels and independent elements\r
                for (Sketch2 sketch : mdl.getSketches()) {\r
                        sketch.setEdges();\r
@@ -234,6 +230,7 @@ public class MdlParser2 {
                                if (line.endsWith("|"))\r
                                        break;\r
                        } while ((line = reader.readLine()) != null);\r
+                       \r
                        String str = buffer.toString();\r
 \r
                        String cat = MdlUtils.getPossibleCategory(str);\r
@@ -247,6 +244,12 @@ public class MdlParser2 {
                                mdl.addVariable(var, category);\r
                                continue;\r
                        }\r
+                       \r
+                       Subscript2 subscript = MdlUtils.getPossibleSubscript(str, mdl);\r
+                       if (subscript != null) {\r
+                               mdl.addSubscript(subscript);\r
+                               continue;\r
+                       }\r
 \r
                        // if we got this far, the variable could not be parsed\r
                        System.err.println("unrecognized variable "+str);\r
index eda44c42866e6d7796fd7944d88ddb5bdf114ff1..d825fc3ef63b3379d36237799b88d0e8231577c9 100644 (file)
@@ -14,6 +14,7 @@ import org.simantics.sysdyn.modelImport.model.SketchConnection;
 import org.simantics.sysdyn.modelImport.model.SketchElement;\r
 import org.simantics.sysdyn.modelImport.model.SketchValve;\r
 import org.simantics.sysdyn.modelImport.model.SketchVariable;\r
+import org.simantics.sysdyn.modelImport.model.Subscript2;\r
 import org.simantics.sysdyn.modelImport.model.Variable2;\r
 import org.simantics.sysdyn.modelImport.model.Valve2.TextPosition;\r
 \r
@@ -40,49 +41,23 @@ public class MdlUtils {
        private static final String VAR_NAME =\r
                        "("+VAR_NAME_QUOTED+"|"+VAR_NAME_SIMPLE+")";\r
        \r
-       private static final String SUBSCRIPT =\r
-                       "("+VAR_NAME_SIMPLE+")\\[("+VAR_NAME_SIMPLE+"(?:,"+VAR_NAME_SIMPLE+")*)\\]";\r
-\r
-       // the first part of the variable string is the variable name \r
-       // followed by a delimiter which depends on the type of the declaration\r
        private static final String VARIABLE_PATTERN =\r
                        VAR_NAME+"\\s*=\\s*";\r
-       private static final String SUBSCRIPT_PATTERN =\r
-                       SUBSCRIPT+"\\s*=\\s*";\r
-       private static final String VALUE_NEW_PATTERN =\r
-                       VAR_NAME+"\\s*:\\s*";\r
-       private static final String VALUE_EQUALS_PATTERN =\r
-                       VAR_NAME+"\\s*<->\\s*";\r
-       \r
-       // the second part is the equation followed by '~'\r
        private static final String EQUATION_PATTERN =\r
                        "([^~]*?(?:"+VAR_NAME_QUOTED+"[^~]*?)*)\\s*~\\s*";\r
-       \r
-       // the third part is the unit followed by '~'\r
        private static final String UNIT_PATTERN =\r
                        "([^~]*?)\\s*~\\s*";\r
-       \r
-       // the last part is the description followed by '|'\r
        private static final String DESC_PATTERN =\r
                        "([^\\|]*?)\\s*\\|";\r
-\r
+       \r
        public static final String variablePattern = \r
                        VARIABLE_PATTERN+EQUATION_PATTERN+UNIT_PATTERN+DESC_PATTERN;\r
-       public static final String subscriptPattern =\r
-                       SUBSCRIPT_PATTERN+EQUATION_PATTERN+UNIT_PATTERN+DESC_PATTERN;\r
-       public static final String valueNewPattern = \r
-                       VALUE_NEW_PATTERN+EQUATION_PATTERN+UNIT_PATTERN+DESC_PATTERN;\r
-       public static final String valueEqualsPattern = \r
-                       VALUE_EQUALS_PATTERN+EQUATION_PATTERN+UNIT_PATTERN+DESC_PATTERN;\r
        \r
        private static final int variableName = 1;\r
        private static final int variableEquation = 2;\r
        private static final int variableUnit = 3;\r
        private static final int variableDesc = 4;\r
        \r
-       private static final String NUMBER = \r
-                       "-?\\d+(?:.\\d+)?";\r
-       \r
        public static Variable2 getPossibleVariable(String line, String category) {\r
                Matcher matcher = Pattern.compile(variablePattern).matcher(line);\r
                \r
@@ -103,6 +78,56 @@ public class MdlUtils {
                return new Variable2(name, expression, unit, range, description);\r
        }\r
        \r
+       // a subscript variable is a variable that has a different equation\r
+       // depending on the value of the subscript it references\r
+       private static final String VAR_NAME_SUBSCRIPT =\r
+                       "("+VAR_NAME_SIMPLE+")\\[("+VAR_NAME_SIMPLE+"(?:,"+VAR_NAME_SIMPLE+")*)\\]";\r
+\r
+       private static final String SUBSCRIPT_VARIABLE_PATTERN =\r
+                       VAR_NAME_SUBSCRIPT+"\\s*=\\s*";\r
+\r
+       public static final String subscriptVariablePattern = \r
+                       SUBSCRIPT_VARIABLE_PATTERN+EQUATION_PATTERN+UNIT_PATTERN+DESC_PATTERN;\r
+       \r
+       private static final int subscriptVariableName = 1;\r
+       private static final int subscriptVariableIndices = 2;\r
+       private static final int subscriptVariableEquation = 3;\r
+       private static final int subscriptVariableUnit = 4;\r
+       private static final int subscriptVariableDesc = 5;\r
+       \r
+       public static Variable2 getPossibleSubscriptVariable(String line, String category) {\r
+               return null;\r
+       }\r
+\r
+       private static final String SUBSCRIPT_PATTERN =\r
+                       "("+VAR_NAME_SIMPLE+")\\s*(:|<->)\\s*";\r
+       \r
+       public static final String subscriptPattern = \r
+                       SUBSCRIPT_PATTERN+EQUATION_PATTERN+UNIT_PATTERN+DESC_PATTERN;\r
+       \r
+       private static final int subscriptName = 1;\r
+       private static final int subscriptType = 2;\r
+       private static final int subscriptEquation = 3;\r
+       \r
+       public static Subscript2 getPossibleSubscript(String line, MdlModel mdl) {\r
+               Matcher matcher = Pattern.compile(subscriptPattern).matcher(line);\r
+               \r
+               if (!matcher.matches()) {\r
+                       return null;\r
+               }\r
+               \r
+               String name = matcher.group(subscriptName);\r
+               boolean equivalence = matcher.group(subscriptType).equals("<->");\r
+               String expression = matcher.group(subscriptEquation);\r
+               \r
+               if (equivalence) {\r
+                       return new Subscript2(name, mdl.getSubscript(expression));\r
+               }\r
+               else {\r
+                       return new Subscript2(name, expression.split(","));\r
+               }\r
+       }\r
+       \r
        private static IExpression parseEquation(String equation) {\r
                if (equation.startsWith("INTEG")) {\r
                        return parseIntegralExpression(equation);\r
@@ -138,17 +163,23 @@ public class MdlUtils {
                return new NormalExpression(normalize(equation));\r
        }\r
        \r
+       private static final String NUMBER = \r
+                       "-?\\d+(?:.\\d+)?";\r
+       \r
        private static Range parseRange(String unit) {\r
-               Matcher matcher = Pattern.compile("\\[("+NUMBER+"),("+NUMBER+"|\\?)\\]").matcher(unit);\r
+               Matcher matcher = Pattern.compile("\\[("+NUMBER+"),(("+NUMBER+"),("+NUMBER+")|\\?)\\]").matcher(unit);\r
                if (matcher.find()) {\r
-                       String start = matcher.group(1);\r
-                       String end = matcher.group(2);\r
-                       // TODO: and step is?\r
-                       return new Range(\r
-                                       Double.parseDouble(start), \r
-                                       end.equals("?") ? null : Double.parseDouble(end), \r
-                                       null, \r
-                                       matcher.group());\r
+                       Double start, end, step;\r
+                       start = Double.parseDouble(matcher.group(1));\r
+                       if (matcher.group(2).equals("?")) {\r
+                               end = null;\r
+                               step = null;\r
+                       }\r
+                       else {\r
+                               end = Double.parseDouble(matcher.group(3));\r
+                               step = Double.parseDouble(matcher.group(4));\r
+                       }\r
+                       return new Range(start, end, step, matcher.group());\r
                }\r
                else {\r
                        return null;\r
@@ -174,8 +205,8 @@ public class MdlUtils {
        private static final String POINTS = "(\\d+\\|(?:\\(-?\\d+,-?\\d+\\)\\|)+)";\r
        \r
        public static final String sketchConnection =\r
-               //   1,  id,  from,to,  shape,hid, pol, thick,hasf,dtype,res,color,font,np|plist\r
-                       "1,"+SAVE+SAVE+SAVE+SAVE+ SKIP+SKIP+SKIP+ SKIP+SKIP+ "0,-1--1--1,.*,"+POINTS;\r
+               //   1,  id,  from,to,  shape,hid, pol, thick,hasf,dtype,res, color,font,np|plist\r
+                       "1,"+SAVE+SAVE+SAVE+SAVE+ SKIP+SKIP+SKIP+ SKIP+SKIP+ SKIP+"[^,]*,[^,]*,"+POINTS;\r
        \r
        // group indices for later use\r
        private static final int connectionId = 1;\r
index 005ca18c15d8e65b495b9d6107cb5fe872c63395..d24e555152a8ec4afc5305f7d91c0b403ff05448 100644 (file)
@@ -38,7 +38,7 @@ public abstract class Element2 implements IWriteableObject {
                return resource;\r
        }\r
 \r
-       public void setResource(Resource resource) {\r
+       protected void setResource(Resource resource) {\r
                this.resource = resource;\r
        }\r
        \r
diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Enumeration2.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Enumeration2.java
new file mode 100644 (file)
index 0000000..00e0b1e
--- /dev/null
@@ -0,0 +1,37 @@
+package org.simantics.sysdyn.modelImport.model;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+\r
+public class Enumeration2 implements IWriteableObject {\r
+       \r
+       private String name;\r
+       private ArrayList<String> values;\r
+       \r
+       private Resource resource;\r
+       \r
+       public Enumeration2(String name, ArrayList<String> values) {\r
+               this.name = name;\r
+               this.values = values;\r
+       }\r
+       \r
+       public String getName() {\r
+               return name;\r
+       }\r
+       \r
+       public Resource getResource() {\r
+               return resource;\r
+       }\r
+\r
+       @Override\r
+       public void write(WriteGraph graph, Resource parent, WriteContext context)\r
+                       throws DatabaseException {\r
+               System.err.println("write enumeration");\r
+               \r
+               resource = null;\r
+       }\r
+\r
+}\r
index 1a5519e89970da56f409b92b5f5e7f6c9e3d26b5..43f8fa64fd221cbe685d01eaf40ee1aa1794042f 100644 (file)
@@ -1,6 +1,7 @@
 package org.simantics.sysdyn.modelImport.model;\r
 \r
 import java.util.ArrayList;\r
+import java.util.Collections;\r
 import java.util.HashMap;\r
 import java.util.List;\r
 \r
@@ -11,12 +12,15 @@ public class MdlModel {
        private HashMap<String, Variable2> variables;\r
        private HashMap<String, ArrayList<Variable2>> groups;\r
        \r
+       private HashMap<String, Subscript2> subscripts;\r
+       \r
        private ArrayList<Sketch2> sketches;\r
        \r
        public MdlModel(String name) {\r
                this.name = name;\r
                this.variables = new HashMap<String, Variable2>();\r
                this.groups = new HashMap<String, ArrayList<Variable2>>();\r
+               this.subscripts = new HashMap<String, Subscript2>();\r
                this.sketches = new ArrayList<Sketch2>();\r
        }\r
        \r
@@ -39,6 +43,23 @@ public class MdlModel {
                return variables.get(name);\r
        }\r
        \r
+       public List<Variable2> getVariables() {\r
+               return new ArrayList<Variable2>(variables.values());\r
+       }\r
+       \r
+       public void addSubscript(Subscript2 subscript) {\r
+               System.err.println("SUBSCRIPT "+subscript.getName()+": "+subscript.getValues());\r
+               subscripts.put(subscript.getName(), subscript);\r
+       }\r
+       \r
+       public Subscript2 getSubscript(String name) {\r
+               return subscripts.get(name);\r
+       }\r
+       \r
+       public List<Subscript2> getSubscripts() {\r
+               return new ArrayList<Subscript2>(subscripts.values());\r
+       }\r
+       \r
        public void addSketch(Sketch2 sketch) {\r
                sketches.add(sketch);\r
        }\r
index 4189cd1911c044eaa42f97e42b3e0ad6a37b9c6e..ca68dad5c73a5fd55fc6427cccac50d79a1a6fca 100644 (file)
@@ -12,6 +12,9 @@
 package org.simantics.sysdyn.modelImport.model;\r
 \r
 import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.HashMap;\r
+import java.util.List;\r
 \r
 import org.simantics.databoard.Bindings;\r
 import org.simantics.db.Resource;\r
@@ -30,6 +33,9 @@ public class Model2 implements IWriteableObject {
        private double start, stop, step;\r
        \r
        // the structure of the model\r
+       private HashMap<String, Enumeration2> enumerations;\r
+       private HashMap<String, ModelVariable> variables;\r
+       \r
        private ArrayList<Element2> elements;\r
        private ArrayList<Shadow2> shadows;\r
        private ArrayList<Connection2> connections;\r
@@ -37,6 +43,9 @@ public class Model2 implements IWriteableObject {
        public Model2(String name) {\r
                this.name = name;\r
                \r
+               enumerations = new HashMap<String, Enumeration2>();\r
+               variables = new HashMap<String, ModelVariable>();\r
+               \r
                elements = new ArrayList<Element2>();\r
                shadows = new ArrayList<Shadow2>();\r
                connections = new ArrayList<Connection2>();\r
@@ -65,6 +74,38 @@ public class Model2 implements IWriteableObject {
        public void setStep(double step) {\r
                this.step = step;\r
        }\r
+       \r
+       public void addEnumeration(Enumeration2 enumeration) {\r
+               if (enumerations.get(enumeration.getName()) != null) {\r
+                       System.err.println("enumeration "+enumeration.getName()+" already defined");\r
+               }\r
+               enumerations.put(enumeration.getName(), enumeration);\r
+       }\r
+       \r
+       public Enumeration2 getEnumeration(String name) {\r
+               return enumerations.get(name);\r
+       }\r
+       \r
+       public Collection<Enumeration2> getEnumerations() {\r
+               return enumerations.values();\r
+       }\r
+       \r
+       public void addVariable(ModelVariable variable) {\r
+               if (enumerations.get(variable.getName()) != null) {\r
+                       System.err.println("variable "+variable.getName()+" already defined");\r
+               }\r
+               variables.put(variable.getName(), variable);\r
+               \r
+               addElement(variable);\r
+       }\r
+       \r
+       public ModelVariable getVariable(String name) {\r
+               return variables.get(name);\r
+       }\r
+       \r
+       public Collection<ModelVariable> getVariables() {\r
+               return variables.values();\r
+       }\r
                \r
        public void addElement(Element2 element) {\r
                elements.add(element);\r
@@ -92,6 +133,10 @@ public class Model2 implements IWriteableObject {
                \r
                Resource configuration = graph.getSingleObject(model, sim.HasConfiguration);\r
                \r
+               for (Enumeration2 e : getEnumerations()) {\r
+                       e.write(graph, configuration, context);\r
+               }\r
+               \r
                for (Element2 e : elements) {\r
                        e.write(graph, configuration, context);\r
                }\r
index 1a5c496d5da5cd334fba2c63bd73a5940e576909..bfa0651a7c66b2d340130f25a35af59afdecd946 100644 (file)
@@ -1,5 +1,7 @@
 package org.simantics.sysdyn.modelImport.model;\r
 \r
+import java.util.List;\r
+\r
 import org.simantics.databoard.Bindings;\r
 import org.simantics.db.Resource;\r
 import org.simantics.db.WriteGraph;\r
@@ -16,6 +18,8 @@ public abstract class ModelVariable extends Element2 {
        protected Range range;\r
        protected String unit;\r
        protected String description;\r
+       \r
+       protected List<Enumeration2> enumerations;\r
 \r
        public ModelVariable(double x, double y, double w, double h, String name, IExpression expression, Range range, String unit, String description) {\r
                super(x, y, w, h);\r
@@ -34,6 +38,10 @@ public abstract class ModelVariable extends Element2 {
                this.unit = variable.getUnit();\r
                this.description = variable.getDescription();\r
        }\r
+       \r
+       public String getName() {\r
+               return name;\r
+       }\r
 \r
        public Resource createVariable(WriteGraph graph, Resource type, Resource parent, WriteContext context) \r
                        throws DatabaseException {\r
@@ -48,6 +56,8 @@ public abstract class ModelVariable extends Element2 {
                \r
                expression.write(graph, variable, context);\r
                \r
+               // TODO: write references to enumerations here?\r
+               \r
                if (range != null) {\r
                        range.write(graph, variable, context);\r
                }\r
diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Subscript2.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Subscript2.java
new file mode 100644 (file)
index 0000000..f2a549e
--- /dev/null
@@ -0,0 +1,29 @@
+package org.simantics.sysdyn.modelImport.model;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+\r
+public class Subscript2 {\r
+       \r
+       private String name;\r
+       private ArrayList<String> values;\r
+       \r
+       public Subscript2(String name, String...values) {\r
+               this.name = name;\r
+               this.values = new ArrayList<String>(Arrays.asList(values));\r
+       }\r
+       \r
+       public Subscript2(String name, Subscript2 other) {\r
+               this.name = name;\r
+               this.values = other.getValues();\r
+       }\r
+       \r
+       public String getName() {\r
+               return name;\r
+       }\r
+       \r
+       public ArrayList<String> getValues() {\r
+               return values;\r
+       }\r
+\r
+}\r
diff --git a/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SubscriptExpression.java b/dev-jkauttio/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/SubscriptExpression.java
new file mode 100644 (file)
index 0000000..6a64637
--- /dev/null
@@ -0,0 +1,45 @@
+package org.simantics.sysdyn.modelImport.model;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+\r
+public class SubscriptExpression implements IExpression {\r
+       \r
+       private ArrayList<SubscriptExpressionElement> elements;\r
+       \r
+       public SubscriptExpression(String[] indices, IExpression expression) {\r
+               elements = new ArrayList<SubscriptExpressionElement>();\r
+               elements.add(new SubscriptExpressionElement(indices, expression));\r
+       }\r
+       \r
+       public List<SubscriptExpressionElement> getElements() {\r
+               return elements;\r
+       }\r
+       \r
+       public void merge(SubscriptExpression other) {\r
+               elements.addAll(other.getElements());\r
+       }\r
+       \r
+       @Override\r
+       public void write(WriteGraph graph, Resource parent, WriteContext context)\r
+                       throws DatabaseException {\r
+               System.err.println("write subscript expression");\r
+       }\r
+       \r
+       private class SubscriptExpressionElement {\r
+               \r
+               String[] indices;\r
+               IExpression expression;\r
+               \r
+               public SubscriptExpressionElement(String[] indices, IExpression expression) {\r
+                       this.indices = indices;\r
+                       this.expression = expression;\r
+               }\r
+       }\r
+\r
+}\r
index f1d365c65247127b232c6cf0b70cec86e99832fd..698ad7ecd9b6b40c0089e5f6d6da94258b3c3a33 100644 (file)
@@ -36,4 +36,10 @@ public class Variable2 {
                return description;\r
        }\r
        \r
+       public void mergeExpression(Variable2 variable) {\r
+               if (expression instanceof SubscriptExpression) {\r
+                       ((SubscriptExpression)expression).merge((SubscriptExpression)variable.getExpression());\r
+               }\r
+       }\r
+       \r
 }\r