]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Initial implementation. Manages to simulate all test models in rootFiles.
authorvillberg <villberg@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Mon, 17 Mar 2014 14:00:56 +0000 (14:00 +0000)
committervillberg <villberg@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Mon, 17 Mar 2014 14:00:56 +0000 (14:00 +0000)
refs #4765

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

49 files changed:
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Addition.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/And.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Application.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Argument.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ArgumentList.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Array.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ArraySliceExpression.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Assignment.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Constant.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Declaration.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Derivate.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Derivative.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Division.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ElementwiseProduct.java [new file with mode: 0644]
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Environment.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Equals.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ForArray.java [new file with mode: 0644]
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ForIndex.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Frame.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Function.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/GreaterOrEqualThan.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/GreaterThan.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IEnvironment.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IExpression.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IfThenElse.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LessOrEqualThan.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LessThan.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LineReader.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Model.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Multiplication.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Negation.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/NodeClass.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/NotEquals.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Or.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ParameterDeclaration.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Parser.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Solver.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Statement.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Subtraction.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/TimeVariable.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Variable.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/VariableBase.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/VariableDeclaration.java
fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelicaParser.jjt
org.simantics.modelica/src/org/simantics/modelica/ModelicaManager.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/OldSysdynExperiment.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynExperiments.java [new file with mode: 0644]
org.simantics.sysdyn/src/org/simantics/sysdyn/solver/InternalSolver.java
org.simantics.sysdyn/src/org/simantics/sysdyn/solver/SysdynSimulationJob.java

index abf31cb45acb08823f340653ab9d7d5d28f1f44a..5e30339752068f92732c8167416e06d27dead1b8 100644 (file)
@@ -31,5 +31,10 @@ public class Addition implements IExpression {
                Double d2 = (Double)exp2.evaluate(environment);\r
                return d1 + d2;\r
        }\r
+       \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               return new Addition(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix));\r
+       }\r
     \r
 }\r
index 0ed114b9d77581384a455d32f037a3a79cae27dd..18f3f1588b59aa1101edd48ec45a177f10b17871 100644 (file)
@@ -36,5 +36,14 @@ public class And implements IExpression {
                for(IExpression e : exps) \r
                        if(!(Boolean)e.evaluate(environment)) return false;\r
                return true;\r
-       }    \r
+       }\r
+       \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               ArrayList<IExpression> ne = new ArrayList<IExpression>();\r
+               for(IExpression e : exps) ne.add(e.withBase(frame, prefix));\r
+               return new And(ne);\r
+       }\r
+\r
+       \r
 }\r
index 4160663c58e0eb93e7e1048de34550781e3dca7f..a8089c411626b3ae23d47b6a10f092a73c44fe01 100644 (file)
@@ -30,4 +30,9 @@ public class Application implements IExpression {
                return environment.getSystem().evaluateFunction(environment, name, args);\r
        }\r
        \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               return new Application(name, args.withBase(frame, prefix));\r
+       }\r
+       \r
 }\r
index e5258945d5eda22a1527f98766f4eb2bd1cdc65e..cbe534d024e6ec0ff3fb446f8670561f271666fb 100644 (file)
@@ -30,4 +30,9 @@ public class Argument implements IExpression {
                throw new UnsupportedOperationException();\r
        }\r
        \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               return new Argument(name, modification.withBase(frame, prefix));\r
+       }\r
+       \r
 }\r
index 9766f08404042b4b5e8a97d3036bd8605716e2cd..f2e637ad1e1ad0c314835b43a658e5666f267464 100644 (file)
@@ -15,13 +15,21 @@ import java.util.ArrayList;
 public class ArgumentList {\r
        \r
     public ArrayList<Argument> args;\r
+    public String op;\r
     \r
     public ArgumentList(ArrayList<Argument> args) {\r
        this.args = args;\r
+       this.op = "";\r
     }\r
 \r
-    public ArgumentList() {\r
+    public ArgumentList(ArrayList<Argument> args, String op) {\r
+       this.args = args;\r
+       this.op = op;\r
+    }\r
+\r
+    public ArgumentList(String op) {\r
        this.args = new ArrayList<Argument>();\r
+       this.op = op;\r
     }\r
 \r
     @Override\r
@@ -37,4 +45,10 @@ public class ArgumentList {
        return b.toString();\r
     }\r
     \r
+    public ArgumentList withBase(IFrame frame, String prefix) {\r
+       ArrayList<Argument> a2 = new ArrayList<Argument>();\r
+       for(Argument a : args) a2.add((Argument)a.withBase(frame, prefix));\r
+       return new ArgumentList(a2, op);\r
+    }\r
+    \r
 }\r
index eeb952b8a93606a17f9e9c6cf83319f9fd56bc62..e6b9a4558d0a2684c6555e7df13365434cafe2e4 100644 (file)
@@ -74,4 +74,22 @@ public class Array implements IExpression {
                for(int i=0;i<needed;i++) addElement(subArray ? new Array() : null);\r
        }\r
        \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               Array result = new Array();\r
+               for(Object o : elements) {\r
+                       if(o instanceof Array) {\r
+                               result.addElement(((Array)o).withBase(frame, prefix));\r
+                       } else {\r
+                               if(o instanceof IExpression) {\r
+                                       IExpression exp = (IExpression)o;\r
+                                       result.addElement(exp.withBase(frame, prefix));\r
+                               } else {\r
+                                       result.addElement(o);\r
+                               }\r
+                       }\r
+               }\r
+               return result;\r
+       }\r
+       \r
 }\r
index b5074cbea5f90dc1fc10b43d992298dede9370d7..e7017bfe380b46999707a64a993aa41161e03587 100644 (file)
@@ -35,4 +35,9 @@ public class ArraySliceExpression implements IExpression {
                return result;\r
        }\r
        \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               return new ArraySliceExpression(start.withBase(frame, prefix), end.withBase(frame, prefix));\r
+       }\r
+       \r
 }\r
index aec5233a0159269ff6a05f61957ace94ab85bd2e..fd7f1d06932b6016278a7dcf4474a9cf88e15aa3 100644 (file)
  *******************************************************************************/\r
 package fi.semantum.sysdyn.solver;\r
 \r
+import org.omg.PortableInterceptor.SUCCESSFUL;\r
+\r
 public class Assignment {\r
        \r
        public Variable target;\r
+       public IExpression[] subscripts;\r
     public IExpression expression;\r
     public boolean assigned = false;\r
     \r
-    public Assignment(Variable target, IExpression expression) {\r
+    public Assignment(Variable target, IExpression[] subscripts, IExpression expression) {\r
        this.target = target;\r
+       this.subscripts = subscripts;\r
        this.expression = expression;\r
     }\r
     \r
@@ -26,4 +30,15 @@ public class Assignment {
        return target + " = " + expression;\r
     }\r
     \r
+    public Assignment withBase(IFrame frame, String prefix) {\r
+       if(subscripts != null) {\r
+               IExpression[] subscripts2 = new IExpression[subscripts.length];\r
+               for(int i=0;i<subscripts.length;i++)\r
+                       subscripts2[i] = subscripts[i].withBase(frame, prefix);\r
+               return new Assignment(target.withBase(frame, prefix), subscripts2, expression.withBase(frame, prefix));\r
+       } else {\r
+               return new Assignment(target.withBase(frame, prefix), null, expression.withBase(frame, prefix));\r
+       }\r
+    }\r
+    \r
 }\r
index 652f27f272d0e6aee5b0e7482d1903f29d9e9012..56bd8b641a4701a02d78ad1545f44b241f02cf72 100644 (file)
@@ -32,4 +32,10 @@ public class Constant implements IExpression {
                return value;\r
        }\r
        \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               return this;\r
+       }\r
+       \r
 }\r
+\r
index 16d45c0325069c3a20859c9becb0e1c61d1e706a..2ef7fd73cd63945f8cbc6e4709e6869d58e4f185 100644 (file)
@@ -31,4 +31,9 @@ public class Declaration implements IExpression {
                throw new UnsupportedOperationException();\r
        }\r
        \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               throw new UnsupportedOperationException();\r
+       }\r
+       \r
 }\r
index 8afcf24c9f200c344b8ceb3efc9db39a3a9f1cc2..b67074e8ae9f1e4ccaef2996341b2150c0ce5b62 100644 (file)
@@ -13,10 +13,12 @@ package fi.semantum.sysdyn.solver;
 public class Derivate implements IExpression {\r
 \r
        private Variable variable;\r
+       private IExpression[] subscripts;\r
        private IExpression e;\r
        \r
-       public Derivate(Variable variable, IExpression e) {\r
+       public Derivate(Variable variable, IExpression[] subscripts, IExpression e) {\r
                this.variable = variable;\r
+               this.subscripts = subscripts;\r
                this.e = e;\r
        }\r
        \r
@@ -24,7 +26,7 @@ public class Derivate implements IExpression {
        public Object evaluate(IEnvironment _environment) {\r
                Environment environment = (Environment)_environment;\r
 //             Double old = (Double)environment.getValue(variable.name + variable.subscriptKey());\r
-               Double old = (Double)environment.getValue(variable.index(_environment));\r
+               Double old = (Double)environment.getValue(variable.index(_environment, subscripts));\r
                return old+environment.step*(Double)e.evaluate(environment);\r
        }\r
        \r
@@ -32,5 +34,17 @@ public class Derivate implements IExpression {
        public String toString() {\r
                return e.toString();\r
        }       \r
+\r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               if(subscripts != null) {\r
+               IExpression[] subscripts2 = new IExpression[subscripts.length];\r
+               for(int i=0;i<subscripts.length;i++)\r
+                       subscripts2[i] = subscripts[i].withBase(frame, prefix);\r
+                       return new Derivate((Variable)variable.withBase(frame, prefix), subscripts2, e.withBase(frame, prefix));\r
+               } else {\r
+                       return new Derivate((Variable)variable.withBase(frame, prefix), null, e.withBase(frame, prefix));\r
+               }\r
+       }\r
        \r
 }\r
index b2abae337b73e7d501e1846a70341ea2c0b058dd..f3fc63318073a2854f7e91f05adc6a239b463dc1 100644 (file)
@@ -10,7 +10,7 @@
  *******************************************************************************/\r
 package fi.semantum.sysdyn.solver;\r
 \r
-public class Derivative {\r
+public class Derivative implements IExpression {\r
 \r
        Variable variable;\r
        \r
@@ -22,5 +22,15 @@ public class Derivative {
        public String toString() {\r
                return "der(" + variable.toString() + ")";\r
        }\r
+\r
+       @Override\r
+       public Object evaluate(IEnvironment environment) {\r
+               throw new UnsupportedOperationException();\r
+       }\r
+       \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               throw new UnsupportedOperationException();\r
+       }\r
        \r
 }\r
index 34ee4e4c0ce0eb8660704cefecadfd564a94cf62..2d31b10783128f408ab27066f99cc8fa6bd4486e 100644 (file)
@@ -26,7 +26,15 @@ public class Division implements IExpression {
     }\r
     \r
     private Array arrayDiv(Array a, Double d) {\r
-       return a;\r
+       Array result = new Array();\r
+       for(Object o : a.elements()) {\r
+               if(o instanceof Double) {\r
+                       result.addElement((Double)o/d);\r
+               } else {\r
+                       throw new IllegalStateException();\r
+               }\r
+       }\r
+       return result;\r
     }\r
     \r
        @Override\r
@@ -39,4 +47,9 @@ public class Division implements IExpression {
                else throw new UnsupportedOperationException();\r
        }\r
        \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               return new Division(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix));\r
+       }\r
+\r
 }\r
diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ElementwiseProduct.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ElementwiseProduct.java
new file mode 100644 (file)
index 0000000..c2b9a5f
--- /dev/null
@@ -0,0 +1,58 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Semantum Oy.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package fi.semantum.sysdyn.solver;\r
+\r
+import java.util.Collection;\r
+import java.util.Iterator;\r
+\r
+public class ElementwiseProduct implements IExpression {\r
+       \r
+    public IExpression exp1;\r
+    public IExpression exp2;\r
+    \r
+    public ElementwiseProduct(IExpression exp1, IExpression exp2) {\r
+       this.exp1 = exp1;\r
+       this.exp2 = exp2;\r
+    }\r
+    \r
+    @Override\r
+    public String toString() {\r
+       return exp1 + " * " + exp2;\r
+    }\r
+    \r
+       @Override\r
+       public Object evaluate(IEnvironment environment) {\r
+               Object left = exp1.evaluate(environment);\r
+               Object right = exp2.evaluate(environment);\r
+               if(left instanceof Array && right instanceof Array) {\r
+                       Array la = (Array)left;\r
+                       Array ra = (Array)right;\r
+                       Collection<Object> lae = la.elements();\r
+                       Collection<Object> rae = ra.elements();\r
+                       if(lae.size() != rae.size()) throw new UnsupportedOperationException();\r
+                       Iterator<Object> li = lae.iterator();\r
+                       Iterator<Object> ri = rae.iterator();\r
+                       Array result = new Array();\r
+                       for(int i=0;i<lae.size();i++) {\r
+                               double ld = (Double)li.next();\r
+                               double rd = (Double)ri.next();\r
+                               result.addElement(ld*rd);\r
+                       }\r
+                       return result;\r
+               } else throw new UnsupportedOperationException();\r
+       }\r
+       \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               return new ElementwiseProduct(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix));\r
+       }\r
+       \r
+}\r
index 5f5db469ff222579c918a0c8d010a9e61c68d4cc..6ab0d2fdc784e7fcd5d84baeb7d80c92865872f6 100644 (file)
  *******************************************************************************/\r
 package fi.semantum.sysdyn.solver;\r
 \r
+import java.util.ArrayList;\r
 import java.util.HashMap;\r
+import java.util.Map;\r
 import java.util.TreeMap;\r
 \r
 interface Fn {\r
        public Object evaluate(IEnvironment environment, int argc);\r
+       public Object evaluateInput(IEnvironment environment, int argPosition);\r
        public void setLocals(IEnvironment environment);\r
        public int offset();\r
        public Variable[] parameters();\r
 }\r
 \r
 abstract class Fn1 implements Fn {\r
+\r
+       Variable[] parameters;\r
        \r
-       static Variable[] parameters;\r
-       \r
-       static {\r
-               parameters = new Variable[5];\r
-               parameters[0] = new Variable(new VariableBase("", 0));\r
-               parameters[1] = new Variable(new VariableBase("", 1));\r
-               parameters[2] = new Variable(new VariableBase("", 2));\r
-               parameters[3] = new Variable(new VariableBase("", 3));\r
-               parameters[4] = new Variable(new VariableBase("", 4));\r
+       public Fn1(int pCount) {\r
+               parameters = new Variable[pCount];\r
+               for(int i=0;i<pCount;i++)\r
+                       parameters[i] = new Variable(new VariableBase("", i));\r
        }\r
        \r
        public int offset() {\r
@@ -46,14 +46,23 @@ abstract class Fn1 implements Fn {
        public void setLocals(IEnvironment environment) {\r
        }\r
        \r
+       @Override\r
+       public Object evaluateInput(IEnvironment environment, int argPosition) {\r
+               // Function frame size is constant - this is called when padding is needed\r
+               return null;\r
+       }\r
+       \r
 }\r
 \r
-public class Environment implements IEnvironment, ISystem {\r
+final public class Environment implements IEnvironment, ISystem {\r
        \r
+       final Map<String,Object> named = new HashMap<String,Object>();\r
+\r
        public Model model;\r
        public final double step;\r
        public double time;\r
        public boolean initial = true;\r
+       public int size;\r
        \r
        public Object[] valueTable;\r
 \r
@@ -64,7 +73,7 @@ public class Environment implements IEnvironment, ISystem {
                this.step = step;\r
                this.time = start;\r
                \r
-               model.functions.put("size", new Fn1() {\r
+               model.functions.put("size", new Fn1(2) {\r
 \r
                        @Override\r
                        public Object evaluate(IEnvironment environment, int argc) {\r
@@ -74,7 +83,7 @@ public class Environment implements IEnvironment, ISystem {
                        }\r
                        \r
                });\r
-               model.functions.put("zidz", new Fn1() {\r
+               model.functions.put("zidz", new Fn1(2) {\r
 \r
                        @Override\r
                        public Object evaluate(IEnvironment environment, int argc) {\r
@@ -85,7 +94,7 @@ public class Environment implements IEnvironment, ISystem {
                        }\r
                        \r
                });\r
-               model.functions.put("xidz", new Fn1() {\r
+               model.functions.put("xidz", new Fn1(3) {\r
 \r
                        @Override\r
                        public Object evaluate(IEnvironment environment, int argc) {\r
@@ -97,7 +106,7 @@ public class Environment implements IEnvironment, ISystem {
                        }\r
                        \r
                });\r
-               model.functions.put("availabilityExternal", new Fn1() {\r
+               model.functions.put("availabilityExternal", new Fn1(4) {\r
 \r
                        @Override\r
                        public Object evaluate(IEnvironment environment, int argc) {\r
@@ -113,7 +122,7 @@ public class Environment implements IEnvironment, ISystem {
                        }\r
                        \r
                });\r
-               model.functions.put("pre", new Fn1() {\r
+               model.functions.put("pre", new Fn1(1) {\r
 \r
                        @Override\r
                        public Object evaluate(IEnvironment environment, int argc) {\r
@@ -123,7 +132,7 @@ public class Environment implements IEnvironment, ISystem {
                        }\r
                        \r
                });\r
-               model.functions.put("fill", new Fn1() {\r
+               model.functions.put("fill", new Fn1(3) {\r
 \r
                        @Override\r
                        public Object evaluate(IEnvironment environment, int argc) {\r
@@ -150,7 +159,7 @@ public class Environment implements IEnvironment, ISystem {
                        }\r
                        \r
                });\r
-               model.functions.put("randomNumber", new Fn1() {\r
+               model.functions.put("randomNumber", new Fn1(2) {\r
 \r
                        @Override\r
                        public Object evaluate(IEnvironment environment, int argc) {\r
@@ -160,7 +169,7 @@ public class Environment implements IEnvironment, ISystem {
                        }\r
                        \r
                });\r
-               model.functions.put("initial", new Fn1() {\r
+               model.functions.put("initial", new Fn1(0) {\r
 \r
                        @Override\r
                        public Object evaluate(IEnvironment _environment, int argc) {\r
@@ -168,7 +177,7 @@ public class Environment implements IEnvironment, ISystem {
                        }\r
                        \r
                });\r
-               model.functions.put("noEvent", new Fn1() {\r
+               model.functions.put("noEvent", new Fn1(1) {\r
 \r
                        @Override\r
                        public Object evaluate(IEnvironment environment, int argc) {\r
@@ -178,7 +187,7 @@ public class Environment implements IEnvironment, ISystem {
                        }\r
                        \r
                });\r
-               model.functions.put("min", new Fn1() {\r
+               model.functions.put("min", new Fn1(5) {\r
 \r
                        @Override\r
                        public Object evaluate(IEnvironment environment, int argc) {\r
@@ -191,7 +200,7 @@ public class Environment implements IEnvironment, ISystem {
                        }\r
                        \r
                });\r
-               model.functions.put("max", new Fn1() {\r
+               model.functions.put("max", new Fn1(5) {\r
 \r
                        @Override\r
                        public Object evaluate(IEnvironment environment, int argc) {\r
@@ -204,7 +213,7 @@ public class Environment implements IEnvironment, ISystem {
                        }\r
                        \r
                });\r
-               model.functions.put("integer", new Fn1() {\r
+               model.functions.put("integer", new Fn1(1) {\r
 \r
                        @Override\r
                        public Object evaluate(IEnvironment environment, int argc) {\r
@@ -215,7 +224,20 @@ public class Environment implements IEnvironment, ISystem {
                        }\r
                        \r
                });\r
-               model.functions.put("delay", new Fn1() {\r
+               model.functions.put("sum", new Fn1(1) {\r
+\r
+                       @Override\r
+                       public Object evaluate(IEnvironment environment, int argc) {\r
+                               Object value = environment.getValue(0);\r
+                               Array arr = (Array)value;\r
+                               double res = 0;\r
+                               for(Object o : arr.elements())\r
+                                       res += (Double)o;\r
+                               return res;\r
+                       }\r
+                       \r
+               });\r
+               model.functions.put("delay", new Fn1(4) {\r
                        \r
                        @Override\r
                        public Object evaluate(IEnvironment _environment, int argc) {\r
@@ -260,9 +282,17 @@ public class Environment implements IEnvironment, ISystem {
                valueTable[key] = value;\r
        }\r
        \r
+       public void put(String key, Object value) {\r
+               named.put(key, value);\r
+       }\r
+\r
+       public void setSize(int size) {\r
+               this.size = size;\r
+       }\r
+       \r
        @Override\r
        public int offset() {\r
-               return model.names.size();\r
+               return size;\r
        }\r
        \r
        @Override\r
@@ -283,30 +313,67 @@ public class Environment implements IEnvironment, ISystem {
        public double time() {\r
                return time;\r
        }\r
+\r
+       double[] valueArray;\r
        \r
+       public String[] getValueKeyArray() {\r
+               \r
+               ArrayList<String> keys = new ArrayList<String>();\r
+               \r
+               for (int i = 0; i < model.assignmentArray.length; i++) {\r
+                       Variable v = model.assignmentArray[i].target;\r
+                       keys.add(v.toString());\r
+               }\r
+               \r
+               for (int i = 0; i < model.derivativeArray.length; i++) {\r
+                       Variable v = model.derivativeArray[i].target;\r
+                       keys.add(v.toString());\r
+               }\r
+               \r
+               // NOTE: there is room for optimization as parameter values that do not\r
+               // change should only be obtained once (and parameter values that do\r
+               // change are (possibly) included in assignments or derivatives)\r
+               for(int i = 0; i < model.parameterArray.length; i++) {\r
+                       Variable v = model.parameterArray[i].variable;\r
+                       keys.add(v.toString());\r
+               }\r
+\r
+               valueArray = new double[keys.size()];\r
+               \r
+               return keys.toArray(new String[keys.size()]);\r
+               \r
+       }\r
+\r
        // TODO: this is probably not smart at all, figure out a better way to obtain results\r
-       public HashMap<String, Double> getValueMap() {\r
-               HashMap<String, Double> values = new HashMap<String, Double>();\r
+       public double[] getValueArray() {\r
+               \r
+               int offset = 0;\r
                \r
                for (int i = 0; i < model.assignmentArray.length; i++) {\r
                        Variable v = model.assignmentArray[i].target;\r
-                       values.put(v.toString(), (Double)getValue(v.index(this)));\r
+                       valueArray[offset++] = (Double)getValue(v.index(this, null));\r
                }\r
                \r
                for (int i = 0; i < model.derivativeArray.length; i++) {\r
                        Variable v = model.derivativeArray[i].target;\r
-                       values.put(v.toString(), (Double)getValue(v.index(this)));\r
+                       valueArray[offset++] = (Double)getValue(v.index(this, null));\r
                }\r
                \r
                // NOTE: there is room for optimization as parameter values that do not\r
                // change should only be obtained once (and parameter values that do\r
                // change are (possibly) included in assignments or derivatives)\r
-               for (ParameterDeclaration p : model.parameters) {\r
-                       Variable v = p.variable;\r
-                       values.put(v.toString(), (Double)getValue(v.index(this)));\r
+               for(int i = 0; i < model.parameterArray.length; i++) {\r
+                       Variable v = model.parameterArray[i].variable;\r
+                       valueArray[offset++] = (Double)getValue(v.index(this, null));\r
                }\r
                \r
-               return values;\r
+               return valueArray;\r
+               \r
+       }\r
+\r
+       @Override\r
+       public Object getNamedValue(String key) {\r
+               return named.get(key);\r
        }\r
 \r
 }\r
index a27a813624209da1ce7bb3952181ad44059be22b..33e5d461aa04303171b654d460fc19416d348c29 100644 (file)
@@ -30,5 +30,9 @@ public class Equals implements IExpression {
                return ((Double)exp1.evaluate(environment)) == ((Double)exp2.evaluate(environment));\r
        }\r
 \r
-    \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               return new Equals(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix));\r
+       }\r
+\r
 }\r
diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ForArray.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ForArray.java
new file mode 100644 (file)
index 0000000..550d7ce
--- /dev/null
@@ -0,0 +1,84 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Semantum Oy.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package fi.semantum.sysdyn.solver;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+public class ForArray implements IExpression {\r
+\r
+       private ArrayList<Object> elements = new ArrayList<Object>();\r
+\r
+       public ForArray() {\r
+               \r
+       }\r
+       \r
+       public void addElement(Object element) {\r
+               if(element instanceof Constant) addElement(((Constant)element).value);\r
+               else elements.add(element);\r
+       }\r
+       \r
+       public void setElement(int index, Object element) {\r
+               elements.set(index, element);\r
+       }\r
+\r
+       @Override\r
+       public Object evaluate(IEnvironment environment) {\r
+               return evaluated(environment);\r
+       }\r
+       \r
+       public Array evaluated(IEnvironment environment) {\r
+               \r
+               Array result = new Array();\r
+               \r
+               IExpression exp = (IExpression)elements.get(0);\r
+               Argument arg = (Argument)elements.get(1);\r
+               \r
+               Array indices = (Array)arg.modification.evaluate(environment);\r
+               for(Object o : indices.elements()) {\r
+                       environment.put(arg.name, o);\r
+//                     Frame f = new Frame(environment, 1);\r
+//                     f.put(arg.name, o);\r
+                       result.addElement(exp.evaluate(environment));\r
+               }\r
+               \r
+               return result;\r
+               \r
+       }\r
+       \r
+       @Override\r
+       public String toString() {\r
+               return elements.toString();\r
+       }\r
+       \r
+       public int size(int col) {\r
+               return elements.size();\r
+       }\r
+       \r
+       public Object element(int index) {\r
+               return elements.get(index);\r
+       }\r
+       \r
+       public Collection<Object> elements() {\r
+               return elements;\r
+       }\r
+       \r
+       public void ensureIndex(int index, boolean subArray) {\r
+               int needed = (index+1-elements.size());\r
+               for(int i=0;i<needed;i++) addElement(subArray ? new ForArray() : null);\r
+       }\r
+       \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               throw new UnsupportedOperationException();\r
+       }\r
+       \r
+}\r
index d4a14eb1f499d74dc4cd8592f17b20ac481f9671..919508166ee4968cd6c8ee7d9ac1c697e5682e5c 100644 (file)
@@ -12,12 +12,15 @@ package fi.semantum.sysdyn.solver;
 \r
 public class ForIndex {\r
        \r
+       public String name;\r
        public VariableBase base;\r
        public IExpression expression;\r
        \r
        public ForIndex(Function function, String name, IExpression expression) {\r
                this.expression = expression;\r
-               this.base = function.addIndex(name, this);\r
+               this.name = name;\r
+               if(function != null)\r
+                       this.base = function.addIndex(name, this);\r
        }\r
        \r
 }\r
index a3b15785726f3f84bea62a46e0ade11d1dd1b3d2..178bf2a046929413a5eae64681a855c40e1c8623 100644 (file)
  *******************************************************************************/\r
 package fi.semantum.sysdyn.solver;\r
 \r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
 public class Frame implements IEnvironment {\r
        \r
        final public IEnvironment parent;\r
        final private int offset;\r
+       Map<String,Object> named;\r
        \r
        public Frame(IEnvironment parent, int offset) {\r
                this.parent = parent;\r
@@ -29,11 +33,22 @@ public class Frame implements IEnvironment {
        public void put(int index, Object value) {\r
                parent.put(parent.offset() + index, value);\r
        }\r
+\r
+       public void put(String key, Object value) {\r
+               if(named == null) named = new HashMap<String,Object>();\r
+               named.put(key, value);\r
+       }\r
        \r
        @Override\r
        public Object getValue(int index) {\r
                return parent.getValue(parent.offset() + index);\r
        }\r
+\r
+       @Override\r
+       public Object getNamedValue(String key) {\r
+               if(named == null) return null;\r
+               return named.get(key);\r
+       }\r
        \r
        @Override\r
        public ISystem getSystem() {\r
index 925a192f988128dfffb9fbe261c8a5db07b911f5..6b76f5b2e7333dec36691316b3cae01a0b194549 100644 (file)
@@ -15,7 +15,7 @@ import java.util.Arrays;
 import java.util.HashMap;\r
 import java.util.Map;\r
 \r
-public class Function implements Fn, IFrame {\r
+final public class Function implements Fn, IFrame {\r
        \r
        public static final boolean PRINT = false;\r
        \r
@@ -106,4 +106,10 @@ public class Function implements Fn, IFrame {
                return parameters;\r
        }\r
        \r
+       @Override\r
+       public Object evaluateInput(IEnvironment environment, int argPosition) {\r
+               VariableDeclaration decl = inputs.get(argPosition);\r
+               return decl.modification.args.get(0).modification.evaluate(environment);\r
+       }\r
+       \r
 }\r
index 3f9fcf561df39bccf4b6f3f0139a2b87a8ed0e44..7b4d396d6bd79e09bba751d1a8da0878c8a10ef3 100644 (file)
@@ -30,5 +30,9 @@ public class GreaterOrEqualThan implements IExpression {
                return ((Double)exp1.evaluate(environment)) >= ((Double)exp2.evaluate(environment));\r
        }\r
 \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               return new GreaterOrEqualThan(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix));\r
+       }\r
     \r
 }\r
index 195547164601176d26d044dd88e0ab4b9fe32835..9f3244ea3a86f82863cc9ac98200eda26bcf37a5 100644 (file)
@@ -30,5 +30,9 @@ public class GreaterThan implements IExpression {
                return ((Double)exp1.evaluate(environment)) > ((Double)exp2.evaluate(environment));\r
        }\r
 \r
-    \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               return new GreaterThan(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix));\r
+       }\r
+\r
 }\r
index 71b6b7388336f4286bc38d0cf7fd46a0cb2b4f9f..036c1e9fa22ada0b27270457b150353ea512b8c7 100644 (file)
@@ -13,8 +13,9 @@ package fi.semantum.sysdyn.solver;
 public interface IEnvironment {\r
 \r
 //     Object getValue(String key);\r
+       Object getNamedValue(String key);\r
        Object getValue(int index);\r
-//     void put(String key, Object value);\r
+       void put(String key, Object value);\r
        void put(int index, Object value);\r
 //     Object evaluateFunction(IEnvironment parent, String name, ArgumentList args);\r
        \r
index e03d07ca18a2a86e822bc86cf5aaabe5ce6e3d93..942b7a3aebb432775c2e240da73eb4c508691368 100644 (file)
@@ -13,5 +13,6 @@ package fi.semantum.sysdyn.solver;
 public interface IExpression {\r
 \r
        public Object evaluate(IEnvironment environment);\r
+       public IExpression withBase(IFrame frame, String prefix);\r
        \r
 }\r
index 72aafc65e3eca71ae1346262775cee3610130a49..ba4bd80179e64d9ebef51d5b30aed4b8df74fb11 100644 (file)
@@ -36,4 +36,9 @@ public class IfThenElse implements IExpression {
                }\r
        }\r
     \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               return new IfThenElse(exp.withBase(frame, prefix), t.withBase(frame, prefix), e.withBase(frame, prefix));\r
+       }\r
+\r
 }\r
index 33295cd1f54ab93aa4fbb0a82fe79a5640f1101d..a1fbc884a4346443da5388caabb154a6e6abc860 100644 (file)
@@ -32,5 +32,9 @@ public class LessOrEqualThan implements IExpression {
                return d1 <= d2;\r
        }\r
 \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               return new LessOrEqualThan(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix));\r
+       }\r
     \r
 }\r
index 6a3aea887eb349e507f6a56aca106f03dbf58fc7..4684ab52fc00be6b463265490e84c7984ba4640e 100644 (file)
@@ -32,4 +32,9 @@ public class LessThan implements IExpression {
                return ((Double)left) < ((Double)right);\r
        }\r
     \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               return new LessThan(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix));\r
+       }\r
+\r
 }\r
index 1dc522fddbe8a35bd110b90a87376d3d115818a7..81ecabc475f2c8774711c233b1d08ed872ff8d50 100644 (file)
@@ -12,6 +12,7 @@ package fi.semantum.sysdyn.solver;
 \r
 import java.io.StringReader;\r
 \r
+import fi.semantum.sysdyn.solver.Model.Globals;\r
 import fi.semantum.sysdyn.solver.parser.ModelParser;\r
 import fi.semantum.sysdyn.solver.parser.Node;\r
 import fi.semantum.sysdyn.solver.parser.SimpleNode;\r
@@ -38,7 +39,7 @@ public class LineReader {
        public LineReader(String input, NodeCache cache) {\r
                chars = input.toCharArray();\r
                this.cache = cache;\r
-               model = new Model();\r
+               model = new Model(new Globals());\r
                parser = new Parser();\r
        }\r
        \r
index 54580e00581019c05275603145fdbe02ac70ea20..11dd72477a2167cefda227bd18d171f5bd1febd3 100644 (file)
@@ -17,6 +17,10 @@ import java.util.Map;
 \r
 class Model implements IFrame {\r
        \r
+       static class Globals {\r
+               public Map<String,Model> classes = new HashMap<String,Model>();\r
+       }\r
+       \r
        final public static boolean PRINT = false;\r
        \r
        public boolean initial = false;\r
@@ -29,6 +33,13 @@ class Model implements IFrame {
        \r
        public Assignment[] assignmentArray;\r
        public Assignment[] derivativeArray;\r
+       public ParameterDeclaration[] parameterArray;\r
+       \r
+       public final Globals globals;\r
+       \r
+       public Model(Globals globals) {\r
+               this.globals = globals;\r
+       }\r
        \r
        public Fn getFunction(String name) {\r
                return functions.get(name);\r
@@ -86,10 +97,15 @@ class Model implements IFrame {
                        \r
                        Variable[] parameters = fn.parameters();\r
                        \r
-                       for(int i=0;i<args.args.size();i++) {\r
+                       for(int i=0;i<parameters.length;i++) {\r
                                Variable var = parameters[i];\r
-                               Object value = argh.get(i);\r
-                               var.assignPlain(frame, value);\r
+                               if(i < argh.size()) {\r
+                                       Object value = argh.get(i);\r
+                                       var.assignPlain(frame, value);\r
+                               } else {\r
+                                       Object value = fn.evaluateInput(environment, i);\r
+                                       var.assignPlain(frame, value);\r
+                               }\r
                        }\r
                        \r
                        fn.setLocals(frame);\r
@@ -129,4 +145,33 @@ class Model implements IFrame {
                \r
        }\r
        \r
+       public void prettyPrint() {\r
+\r
+               System.err.println("initials");\r
+               for(Assignment a : initials) {\r
+                       System.err.println("-"+a);\r
+               }\r
+               System.err.println("assignments");\r
+               for(Assignment a : assignments) {\r
+                       System.err.println("-"+a);\r
+               }\r
+               System.err.println("derivatives");\r
+               for(Assignment a : derivatives) {\r
+                       System.err.println("-"+a);\r
+               }\r
+               System.err.println("parameters");\r
+               for(ParameterDeclaration a : parameters) {\r
+                       System.err.println("-"+a);\r
+               }\r
+               System.err.println("variables");\r
+               for(VariableDeclaration a : variables) {\r
+                       System.err.println("-"+a);\r
+               }\r
+               System.err.println("functions");\r
+               for(Map.Entry<String, Fn> a : functions.entrySet()) {\r
+                       System.err.println("-"+a.getKey() + " " + a.getValue());\r
+               }\r
+               \r
+       }\r
+       \r
 }
\ No newline at end of file
index 8721c27d76b3c3486ae74024f9ef30d970425b8c..cb41f9dd51d1f0046c48f0f0aeb15d5e0dcf02c7 100644 (file)
@@ -26,7 +26,15 @@ public class Multiplication implements IExpression {
     }\r
 \r
     private Array arrayMul(Array a, Double d) {\r
-       return a;\r
+       Array result = new Array();\r
+       for(Object o : a.elements()) {\r
+               if(o instanceof Double) {\r
+                       result.addElement((Double)o*d);\r
+               } else {\r
+                       throw new IllegalStateException();\r
+               }\r
+       }\r
+       return result;\r
     }\r
     \r
        @Override\r
@@ -38,4 +46,10 @@ public class Multiplication implements IExpression {
                else if (left instanceof Double && right instanceof Array) return arrayMul((Array)right, (Double)left);\r
                else throw new UnsupportedOperationException();\r
        }\r
+       \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               return new Multiplication(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix));\r
+       }\r
+       \r
 }\r
index d20354dd3b8e3cb34f340564ce00e6ccbd8ae982..e810c27868536eb6799b338ebbfc9de802b70b1d 100644 (file)
@@ -28,4 +28,9 @@ public class Negation implements IExpression {
                return -((Double)exp.evaluate(environment));\r
        }\r
     \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               return new Negation(exp.withBase(frame, prefix));\r
+       }\r
+\r
 }\r
index 2d8c909a84aeaaf3e4ba442038f51a80b2dd724d..9777c7d8847c640b3742eb6a5cce7e76402f0a8e 100644 (file)
@@ -22,6 +22,7 @@ public enum NodeClass {
        while_statement,\r
        statement,\r
        name,\r
+       element,\r
        element_list,\r
        element_modification,\r
        function_arguments,\r
index e5bee880bed978665c978e0909fbf03c62cc419e..f6056732e5b470067b82baff16892f05aaeb545d 100644 (file)
@@ -30,5 +30,9 @@ public class NotEquals implements IExpression {
                return ((Double)exp1.evaluate(environment)) != ((Double)exp2.evaluate(environment));\r
        }\r
 \r
-    \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               return new NotEquals(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix));\r
+       }\r
+\r
 }\r
index 1e72912a718503f238aca7c9294930e113cae94f..cdc907e093a49dd5b1a2b70722692d91231ff3c6 100644 (file)
@@ -36,5 +36,13 @@ public class Or implements IExpression {
                for(IExpression e : exps) \r
                        if((Boolean)e.evaluate(environment)) return true;\r
                return false;\r
-       }    \r
+       }\r
+       \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               ArrayList<IExpression> ne = new ArrayList<IExpression>();\r
+               for(IExpression e : exps) ne.add(e.withBase(frame, prefix));\r
+               return new Or(ne);\r
+       }\r
+       \r
 }\r
index 1c3b04571335dc0ff331b1abc67fc7a0fe7ade9d..b3eca9028f34b0a67b44a35c6a72776c3be3a582 100644 (file)
@@ -32,4 +32,9 @@ public class ParameterDeclaration implements IExpression {
                throw new UnsupportedOperationException();\r
        }\r
        \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               throw new UnsupportedOperationException();\r
+       }\r
+       \r
 }\r
index 0b1f5aad6b127e5916808af5e4271dac4028e386..195e19d63bf9977893b1a212274988db71708ffb 100644 (file)
  *******************************************************************************/\r
 package fi.semantum.sysdyn.solver;\r
 \r
+import java.io.File;\r
+import java.io.StringReader;\r
 import java.util.ArrayList;\r
 import java.util.HashMap;\r
 import java.util.Map;\r
 \r
+import org.simantics.utils.FileUtils;\r
+\r
+import fi.semantum.sysdyn.solver.Model.Globals;\r
+import fi.semantum.sysdyn.solver.parser.ModelParser;\r
 import fi.semantum.sysdyn.solver.parser.SimpleNode;\r
 \r
 public class Parser {\r
@@ -55,11 +61,12 @@ public class Parser {
                        IExpression exp = (IExpression)walk((SimpleNode)n.jjtGetChild(1), indent+2, model);\r
                        if(v instanceof Derivative) {\r
                                Derivative der = (Derivative)v;\r
-                               Assignment eq = new Assignment(der.variable,new Derivate(der.variable, exp));\r
+                               Assignment eq = new Assignment(der.variable, der.variable.subscripts, new Derivate(der.variable, der.variable.subscripts, exp));\r
                                model.derivatives.add(eq);\r
                                return eq;\r
                        } else {\r
-                               Assignment eq = new Assignment((Variable)v,exp);\r
+                               Variable var = (Variable)v;\r
+                               Assignment eq = new Assignment(var, var.subscripts, exp);\r
                                if(model.initial)\r
                                        model.initials.add(eq);\r
                                else\r
@@ -69,10 +76,16 @@ public class Parser {
                case equation_section:\r
                        if("initial".equals(n.op)) {\r
                                model.initial = true;\r
+                               for(int i=0;i<n.jjtGetNumChildren();i++) {\r
+                                       walk((SimpleNode)n.jjtGetChild(i),indent+2, model);\r
+                               }\r
                        } else {\r
                                model.initial = false;\r
+                               for(int i=0;i<n.jjtGetNumChildren();i++) {\r
+                                       walk((SimpleNode)n.jjtGetChild(i),indent+2, model);\r
+                               }\r
                        }\r
-                       break;\r
+                       return null;\r
                case composition:\r
                        if(n.jjtGetNumChildren() == 1) return walk((SimpleNode)n.jjtGetChild(0),indent+2, model);\r
                        ArrayList<Object> comps = new ArrayList<Object>();\r
@@ -81,7 +94,10 @@ public class Parser {
                        }\r
                        return comps;\r
                case for_index:\r
-                       return new ForIndex((Function)currentFrame, n.op, (IExpression)walk((SimpleNode)n.jjtGetChild(0),indent+2, model));\r
+                       if(currentFrame instanceof Function)\r
+                               return new ForIndex((Function)currentFrame, n.op, (IExpression)walk((SimpleNode)n.jjtGetChild(0),indent+2, model));\r
+                       else\r
+                               return new ForIndex(null, n.op, (IExpression)walk((SimpleNode)n.jjtGetChild(0),indent+2, model));\r
                case for_indices:\r
                        ArrayList<ForIndex> indices = new ArrayList<ForIndex>();\r
                        for(int i=0;i<n.jjtGetNumChildren();i++) {\r
@@ -116,7 +132,7 @@ public class Parser {
                        if(n.jjtGetNumChildren() == 1) return (IStatement)walk((SimpleNode)n.jjtGetChild(0), indent+2, model);\r
                        Variable variable = (Variable)walk((SimpleNode)n.jjtGetChild(0), indent+2, model);\r
                        IExpression expression2 = (IExpression)walk((SimpleNode)n.jjtGetChild(1), indent+2, model);\r
-                       return new Statement(variable, expression2);\r
+                       return new Statement(variable, variable.subscripts, expression2);\r
                case name:\r
                        return n.op;\r
                case element_list:\r
@@ -125,6 +141,12 @@ public class Parser {
                                elements.add(walk((SimpleNode)n.jjtGetChild(i),indent+2, model));\r
                        }\r
                        return elements;\r
+               case element:\r
+//                     if("inner".equals(n.op)) {\r
+//                             return null;\r
+//                     } else {\r
+                               return walk((SimpleNode)n.jjtGetChild(0),indent+2, model);\r
+//                     }\r
                case element_modification:\r
                        if(n.jjtGetNumChildren() == 2) {\r
                                String name = (String)walk((SimpleNode)n.jjtGetChild(0), indent+2, model);\r
@@ -133,13 +155,23 @@ public class Parser {
                        }\r
                        break;\r
                case function_arguments:\r
-                       ArgumentList arguments = new ArgumentList();\r
+                       ArgumentList arguments = new ArgumentList(n.op);\r
                        for(int i=0;i<n.jjtGetNumChildren();i++) {\r
                                Object o = walk((SimpleNode)n.jjtGetChild(i),indent+2, model);\r
                                if(o instanceof ArgumentList) {\r
                                        arguments.args.addAll(((ArgumentList)o).args);\r
                                } else if (o instanceof IExpression) {\r
                                        arguments.args.add(new Argument("", (IExpression)o));\r
+                               } else if (o instanceof ArrayList) {\r
+                                       ArrayList list = (ArrayList)o;\r
+                                       for(Object o2 : list) {\r
+                                               if(o2 instanceof Argument) {\r
+                                                       arguments.args.add((Argument)o2);\r
+                                               } else if (o2 instanceof ForIndex) {\r
+                                                       ForIndex fi = (ForIndex)o2;\r
+                                                       arguments.args.add(new Argument(fi.name, fi.expression));\r
+                                               }\r
+                                       }\r
                                } else {\r
                                        return null;\r
                                }\r
@@ -185,12 +217,57 @@ public class Parser {
                                } else {\r
                                        if(decl.modification instanceof ArgumentList) {\r
                                                VariableDeclaration vd = new VariableDeclaration(decl.variable, type_prefix, type_specifier, (ArgumentList)decl.modification);\r
-                                               if(currentFrame == model) model.variables.add(vd);\r
+                                               model.variables.add(vd);\r
                                                clauses.add(vd);\r
-                                       } else  {\r
-                                               VariableDeclaration vd = new VariableDeclaration(decl.variable, type_prefix, type_specifier, new ArgumentList(new ArrayList<Argument>()));\r
-                                               if(currentFrame == model) model.variables.add(vd);\r
+                                       } else if (decl.modification instanceof IExpression) {\r
+                                               ArrayList<Argument> as = new ArrayList<Argument>();\r
+                                               as.add(new Argument("", (IExpression)decl.modification));\r
+                                               ArgumentList al = new ArgumentList(as);\r
+                                               VariableDeclaration vd = new VariableDeclaration(decl.variable, type_prefix, type_specifier, al);\r
+                                               model.variables.add(vd);\r
                                                clauses.add(vd);\r
+                                       } else  {\r
+                                               if("Real".equals(type_specifier)) {\r
+                                                       VariableDeclaration vd = new VariableDeclaration(decl.variable, type_prefix, type_specifier, new ArgumentList(new ArrayList<Argument>()));\r
+                                                       model.variables.add(vd);\r
+                                                       clauses.add(vd);\r
+                                               } else if("Integer".equals(type_specifier)) {\r
+                                                       VariableDeclaration vd = new VariableDeclaration(decl.variable, type_prefix, type_specifier, new ArgumentList(new ArrayList<Argument>()));\r
+                                                       model.variables.add(vd);\r
+                                                       clauses.add(vd);\r
+                                               } else if("Boolean".equals(type_specifier)) {\r
+                                                       VariableDeclaration vd = new VariableDeclaration(decl.variable, type_prefix, type_specifier, new ArgumentList(new ArrayList<Argument>()));\r
+                                                       model.variables.add(vd);\r
+                                                       clauses.add(vd);\r
+                                               } else {\r
+                                                       Model clazz = model.globals.classes.get(type_specifier);\r
+                                                       for(VariableDeclaration vd : clazz.variables) {\r
+                                                               String base = decl.variable.base.name + ".";\r
+                                                               Variable var2 = vd.variable.withBase(currentFrame, base);\r
+                                                               VariableDeclaration vd2 = new VariableDeclaration(var2, vd.direction, vd.type, vd.modification.withBase(currentFrame, base));\r
+                                                               model.variables.add(vd2);\r
+                                                               clauses.add(vd2);\r
+                                                       }\r
+                                                       for(ParameterDeclaration pd : clazz.parameters) {\r
+                                                               String base = decl.variable.base.name + ".";\r
+                                                               Variable var2 = pd.variable.withBase(currentFrame, base);\r
+                                                               ParameterDeclaration pd2 = new ParameterDeclaration(var2, pd.modification.withBase(currentFrame, base));\r
+                                                               model.parameters.add(pd2);\r
+                                                       }\r
+                                                       for(Assignment ass : clazz.assignments) {\r
+                                                               Assignment ass2 = ass.withBase(currentFrame, decl.variable.base.name + ".");\r
+                                                               model.assignments.add(ass2);\r
+                                                       }\r
+                                                       for(Assignment ass : clazz.initials) {\r
+                                                               Assignment ass2 = ass.withBase(currentFrame, decl.variable.base.name + ".");\r
+                                                               model.initials.add(ass2);\r
+                                                       }\r
+                                                       for(Assignment ass : clazz.derivatives) {\r
+                                                               Assignment ass2 = ass.withBase(currentFrame, decl.variable.base.name + ".");\r
+                                                               model.derivatives.add(ass2);\r
+                                                       }\r
+                                                       \r
+                                               }\r
                                        }\r
                                }\r
                        }\r
@@ -261,15 +338,46 @@ public class Parser {
                                model.functions.put(functionName, function);\r
                                currentFrame = model;\r
                                return function;\r
+                               \r
+                       } else if("model".equals(n.op)) {\r
+\r
+                               currentFrame = model;\r
+\r
+                               if(n.jjtGetNumChildren() == 1) {\r
+                                       return walk((SimpleNode)n.jjtGetChild(0), indent+2, model);\r
+                               } else {\r
+                                       System.err.println("undefined children for class_definition model");    \r
+                               }\r
+                               return null;\r
+                               \r
+                       } else if("class".equals(n.op)) {\r
+                               \r
+                               Model clazz = new Model(model.globals);\r
+                               SimpleNode specifier = (SimpleNode)n.jjtGetChild(0); \r
+                               model.globals.classes.put(specifier.op, clazz);\r
+                               currentFrame = clazz;\r
+                               walk(specifier, indent+2, clazz);\r
+                               currentFrame = model;\r
+                               return null;\r
+                               \r
+                       } else {\r
+                               System.err.println("class_definition " + n.op);\r
                        }\r
                        break;\r
                case array:\r
-                       Array array = new Array();\r
                        if(n.jjtGetNumChildren() == 1) {\r
                                ArgumentList al = (ArgumentList)walk((SimpleNode)n.jjtGetChild(0), indent+2, model);\r
-                               for(Argument arg : al.args) array.addElement(arg.modification);\r
+                               if("for".equals(al.op)) {\r
+                                       ForArray array = new ForArray();\r
+                                       array.addElement(al.args.get(0).modification);\r
+                                       array.addElement(al.args.get(1));\r
+                                       return array;\r
+                               } else {\r
+                                       Array array = new Array();\r
+                                       for(Argument arg : al.args) array.addElement(arg.modification);\r
+                                       return array;\r
+                               }\r
                        }\r
-                       return array;\r
                case primary:\r
                        if(n.op != null) {\r
                                return Utils.parsePrimitive(n.op);\r
@@ -338,22 +446,31 @@ public class Parser {
                                return walk((SimpleNode)n.jjtGetChild(0), indent+2, model);\r
                        }\r
                case arithmetic_expression:\r
-                       if(n.jjtGetNumChildren() == 2) {\r
+               {\r
+                       int i=0;\r
+                       IExpression left;\r
+                       if(n.jjtGetNumChildren() % 2 == 0) {\r
                                String op = ((String)walk((SimpleNode)n.jjtGetChild(0), indent+2, model)).trim();\r
-                               if("-".equals(op)) return new Negation((IExpression)walk((SimpleNode)n.jjtGetChild(1), indent+2, model));\r
-                       }\r
-                       if(n.jjtGetNumChildren() > 1) {\r
-                               IExpression left = (IExpression)walk((SimpleNode)n.jjtGetChild(0), indent+2, model);\r
-                               for(int i=1;i<n.jjtGetNumChildren();i+=2) {\r
-                                       String op = ((String)walk((SimpleNode)n.jjtGetChild(i), indent+2, model)).trim();\r
-                                       IExpression exp2 = (IExpression)walk((SimpleNode)n.jjtGetChild(i+1), indent+2, model);\r
-                                       if("+".equals(op)) left = new Addition(left, exp2);\r
-                                       else if("-".equals(op)) left = new Subtraction(left, exp2);\r
+                               left = (IExpression)walk((SimpleNode)n.jjtGetChild(1), indent+2, model);\r
+                               if("-".equals(op)) {\r
+                                       left = new Negation(left);\r
                                }\r
-                               return left;\r
+                               i=2;\r
                        } else {\r
-                               return walk((SimpleNode)n.jjtGetChild(0), indent+2, model);\r
+                               left = (IExpression)walk((SimpleNode)n.jjtGetChild(0), indent+2, model);\r
+                               i=1;\r
+                       }\r
+\r
+                       for(;i<n.jjtGetNumChildren();i+=2) {\r
+                               String op = ((String)walk((SimpleNode)n.jjtGetChild(i), indent+2, model)).trim();\r
+                               IExpression exp2 = (IExpression)walk((SimpleNode)n.jjtGetChild(i+1), indent+2, model);\r
+                               if("+".equals(op)) left = new Addition(left, exp2);\r
+                               else if("-".equals(op)) left = new Subtraction(left, exp2);\r
                        }\r
+\r
+                       return left;\r
+               }\r
+                       \r
                case term:\r
                        if(n.jjtGetNumChildren() > 1) {\r
                                IExpression term = (IExpression)walk((SimpleNode)n.jjtGetChild(0), indent+2, model);\r
@@ -361,6 +478,7 @@ public class Parser {
                                        String op = ((String)walk((SimpleNode)n.jjtGetChild(i), indent+2, model)).trim();\r
                                        IExpression exp2 = (IExpression)walk((SimpleNode)n.jjtGetChild(i+1), indent+2, model);\r
                                        if("*".equals(op)) term = new Multiplication(term, exp2);\r
+                                       else if(".*".equals(op)) term = new ElementwiseProduct(term, exp2);\r
                                        else if("/".equals(op)) term = new Division(term, exp2);\r
                                }\r
                                return term;\r
@@ -387,7 +505,7 @@ public class Parser {
                                        return new Derivative((Variable)args2.args.get(0).modification);\r
                                }\r
                        } else if("initial".equals(n.op)) {\r
-                               return new Application("initial", new ArgumentList());\r
+                               return new Application("initial", new ArgumentList(""));\r
                        } else if("application".equals(n.op)) {\r
                                String name = (String)walk((SimpleNode)n.jjtGetChild(0), indent+2, model);\r
                                ArgumentList args2 = (ArgumentList)walk((SimpleNode)n.jjtGetChild(1), indent+2, model);\r
@@ -395,8 +513,98 @@ public class Parser {
                        }\r
                }\r
                        \r
+               System.err.println("fall-through " + n);\r
+               \r
                // should not get this far\r
                return null;\r
        }\r
        \r
+       public static final boolean WAIT = false;\r
+       \r
+       public static void main(String[] args) throws Exception {\r
+               \r
+               if(WAIT) {\r
+                       for(int i=0;i<1e12;i++) {\r
+                               int k = System.in.read();\r
+                               if(k==13) break;\r
+                               Thread.sleep(10);\r
+                       }\r
+               }\r
+               \r
+//             NodeCache cache = new NodeCache();\r
+//\r
+////           long start = System.nanoTime();\r
+//\r
+//             File f = new File("C:/Users/Antti Villberg/Downloads/isomalli.txt");\r
+//             String contents = FileUtils.getContents(f);\r
+//             LineReader reader = new LineReader(contents, cache);\r
+//             reader.parse();\r
+//\r
+////           long duration = System.nanoTime()-start;\r
+////           System.err.println("complete parse file in " + 1e-9*duration + "s.");\r
+//\r
+////           start = System.nanoTime();\r
+//\r
+//             if(WAIT) {\r
+//                     for(int i=0;i<1e12;i++) {\r
+//                             int k = System.in.read();\r
+//                             if(k==13) break;\r
+//                             Thread.sleep(10);\r
+//                     }\r
+//             }\r
+\r
+               \r
+\r
+               \r
+               File f1 = new File("d:/sysdynfn.txt");\r
+               String contents1 = FileUtils.getContents(f1);\r
+               File f2 = new File("d:/sysdyntest.txt");\r
+               String contents2 = contents1 + FileUtils.getContents(f2);\r
+               \r
+               StringReader reader = new StringReader(contents2);\r
+               ModelParser modelParser = new ModelParser(reader);\r
+               SimpleNode n = (SimpleNode)modelParser.stored_definition();\r
+           System.err.println("n: " +n );\r
+           Parser parser = new Parser();\r
+           Model m = new Model(new Globals());\r
+               parser.walk(n, 0, m);\r
+               \r
+               m.prettyPrint();\r
+               \r
+//              ModelicaCompilationUnit unit = ModelicaAnalyzer.analyze(contents2);\r
+//              System.err.println("unit: " + unit);\r
+               \r
+\r
+//             reader = new LineReader(contents2, cache);\r
+//             reader.parse();\r
+//             Model model = reader.model;\r
+               \r
+//             String code = FileUtils.getContents(f);\r
+//             Model model = new Parser().parseModelica(code);\r
+               \r
+//             duration = System.nanoTime()-start;\r
+//             System.err.println("parsed file in " + 1e-9*duration + "s.");\r
+\r
+               Solver solver = new Solver();\r
+               solver.prepare(contents2);\r
+               \r
+//\r
+//             if(WAIT) {\r
+//                     for(int i=0;i<1e12;i++) {\r
+//                             int k = System.in.read();\r
+//                             if(k==13) break;\r
+//                             Thread.sleep(10);\r
+//                     }\r
+//             }\r
+//\r
+//             long start = System.nanoTime();\r
+               for(int i=0;i<50;i++) {\r
+                       solver.step();\r
+                       solver.printEnvironment();\r
+               }\r
+//             long duration = System.nanoTime()-start;\r
+//             System.err.println("stepped simulation in " + 1e-9*duration + "s.");\r
+               \r
+       }\r
+       \r
 }\r
index 283db97049267050d8e93699aa06de44b06d52bb..5db6b3347e375b5076cdd29a2a6ba502f61ec2c6 100644 (file)
  *******************************************************************************/\r
 package fi.semantum.sysdyn.solver;\r
 \r
+import java.io.StringReader;\r
 import java.util.ArrayList;\r
-import java.util.HashMap;\r
+\r
+import fi.semantum.sysdyn.solver.Model.Globals;\r
+import fi.semantum.sysdyn.solver.parser.ModelParser;\r
+import fi.semantum.sysdyn.solver.parser.SimpleNode;\r
 \r
 public class Solver {\r
 \r
@@ -48,13 +52,25 @@ public class Solver {
        }\r
        \r
        public void prepare(String input) throws Exception {\r
-               LineReader reader = new LineReader(input, cache);\r
-               reader.parse();\r
                \r
-               model = reader.model;\r
+               long startNanos = System.nanoTime();\r
+               \r
+//             LineReader reader = new LineReader(input, cache);\r
+//             reader.parse();\r
+//             \r
+//             model = reader.model;\r
+               \r
+               StringReader reader = new StringReader(input);\r
+               ModelParser modelParser = new ModelParser(reader);\r
+               SimpleNode n = (SimpleNode)modelParser.stored_definition();\r
+           Parser parser = new Parser();\r
+           model = new Model(new Globals());\r
+               parser.walk(n, 0, model);\r
+               \r
                env = new Environment(model, step, start);\r
                \r
                int size = model.prepare();\r
+               env.setSize(size);\r
                \r
                for(Fn fn : model.functions.values()) {\r
                        if(fn instanceof Function)\r
@@ -65,6 +81,7 @@ public class Solver {
                \r
                model.assignmentArray = model.assignments.toArray(new Assignment[model.assignments.size()]);\r
                model.derivativeArray = model.derivatives.toArray(new Assignment[model.derivatives.size()]);\r
+               model.parameterArray = model.parameters.toArray(new ParameterDeclaration[model.parameters.size()]);\r
                \r
                newValues = new Object[Math.max(model.assignments.size(),model.derivatives.size())];\r
                \r
@@ -77,7 +94,7 @@ public class Solver {
                        for(ParameterDeclaration pd : model.parameters) {\r
                                try {\r
                                        if(!pd.assigned) {\r
-                                               pd.variable.assign(env, pd.modification.evaluate(env));\r
+                                               pd.variable.assign(env, null, pd.modification.evaluate(env));\r
                                                pd.assigned = true;\r
                                        }\r
                                } catch (Exception e) {\r
@@ -99,7 +116,7 @@ public class Solver {
                                                for(Argument arg : vd.modification.args) {\r
                                                        if("start".equals(arg.name)) {\r
                                                                Object value = arg.modification.evaluate(env);\r
-                                                               vd.variable.assign(env, value);\r
+                                                               vd.variable.assign(env, null, value);\r
                                                                // make sure the variable is not initialized \r
                                                                // twice, this is probably not the most \r
                                                                // efficient way\r
@@ -125,7 +142,7 @@ public class Solver {
                                try {\r
                                        if(!ass.assigned) {\r
                                                Object value = ass.expression.evaluate(env);\r
-                                               ass.target.assign(env, value);\r
+                                               ass.target.assign(env, ass.subscripts, value);\r
                                                ass.assigned = true;\r
                                        }\r
                                } catch (Exception e) {\r
@@ -141,10 +158,19 @@ public class Solver {
                env.initial = false;\r
                \r
                ready = true;\r
+               \r
+               long endNanos = System.nanoTime();\r
+               \r
+               System.err.println("Prepared model in " + 1e-6*(endNanos-startNanos) + "ms.");\r
+               \r
+       }\r
+       \r
+       public String[] keys() {\r
+               return env.getValueKeyArray();\r
        }\r
        \r
-       public HashMap<String, Double> values() {\r
-               return env.getValueMap();\r
+       public double[] values() {\r
+               return env.getValueArray();\r
        }\r
        \r
        public void step() {\r
@@ -162,7 +188,7 @@ public class Solver {
                        newValues[i] = assignments[i].expression.evaluate(env);\r
                }\r
                for(int i=0;i<model.assignments.size();i++) {\r
-                       assignments[i].target.assign(env, newValues[i]);\r
+                       assignments[i].target.assign(env, assignments[i].subscripts, newValues[i]);\r
                }\r
 \r
                // Solve derivatives\r
@@ -170,10 +196,19 @@ public class Solver {
                        newValues[i] = derivatives[i].expression.evaluate(env);\r
                }\r
                for(int i=0;i<model.derivatives.size();i++) {\r
-                       derivatives[i].target.assign(env, newValues[i]);\r
+                       derivatives[i].target.assign(env, assignments[i].subscripts, newValues[i]);\r
                }\r
        }\r
        \r
        // TODO: implement some on the fly parameter change stuff for different experiment types\r
        \r
+       public void printEnvironment() {\r
+               System.err.println("Environment");\r
+               String[] keys = keys();\r
+               double[] values = values();\r
+               for(int i=0;i<keys.length;i++) {\r
+                       System.err.println(keys[i] + " = " + values[i]);\r
+               }\r
+       }\r
+       \r
 }\r
index 3b5afcf322744827d9b8ef6cd6f053b965a30254..a3dcd40f80c5c81174479238f4f0d58613e43fe4 100644 (file)
@@ -13,10 +13,12 @@ package fi.semantum.sysdyn.solver;
 public class Statement implements IStatement {\r
        \r
        public Variable target;\r
+       public IExpression[] subscripts;\r
     public IExpression expression;\r
     \r
-    public Statement(Variable target, IExpression expression) {\r
+    public Statement(Variable target, IExpression[] subscripts, IExpression expression) {\r
        this.target = target;\r
+       this.subscripts = subscripts;\r
        this.expression = expression;\r
     }\r
     \r
@@ -28,7 +30,7 @@ public class Statement implements IStatement {
     @Override\r
     public void evaluate(IEnvironment environment) {\r
                Object value = expression.evaluate(environment);\r
-               target.assign(environment, value);\r
+               target.assign(environment, subscripts, value);\r
     }\r
     \r
 }\r
index fcf261e95a3b94c736ea411285d3626871954fa7..4d45af7022663a2896ea270647e45970a6bbea41 100644 (file)
@@ -29,5 +29,11 @@ public class Subtraction implements IExpression {
        public Object evaluate(IEnvironment environment) {\r
                return ((Double)exp1.evaluate(environment)) - ((Double)exp2.evaluate(environment));\r
        }\r
+       \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               return new Subtraction(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix));\r
+       }\r
+       \r
     \r
 }\r
index c6a7251505345bc2de07de3883dc7cb408d4d95c..8a4178ee78b0454695527568d061582eea057117 100644 (file)
@@ -23,4 +23,10 @@ public class TimeVariable implements IExpression {
                return "time";\r
        }\r
        \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               return this;\r
+       }\r
+\r
+       \r
 }\r
index 055310498430f3c606fbfeed92620bf9c35418dd..632fc537ec8a93f21e6fdcc79798f8c9cc3aeb88 100644 (file)
@@ -11,6 +11,9 @@
  *******************************************************************************/\r
 package fi.semantum.sysdyn.solver;\r
 \r
+import org.omg.PortableInterceptor.SUCCESSFUL;\r
+\r
+\r
 public class Variable implements IExpression {\r
 \r
        public VariableBase base;\r
@@ -25,6 +28,11 @@ public class Variable implements IExpression {
                this.base = base;\r
        }\r
 \r
+       public Variable(VariableBase base, IExpression[] subscripts) {\r
+               this.base = base;\r
+               this.subscripts = subscripts;\r
+       }\r
+\r
        private int makeSubscriptIndex(IEnvironment env) {\r
                if(base.dimensions == null) return 0;\r
                int result = 0;\r
@@ -42,7 +50,7 @@ public class Variable implements IExpression {
 \r
        }\r
        \r
-       public int subscriptIndex(IEnvironment env) {\r
+       public int subscriptIndex(IEnvironment env, IExpression[] subscripts) {\r
                if(subscripts == null) return 0;\r
                return makeSubscriptIndex(env);\r
        }\r
@@ -70,7 +78,12 @@ public class Variable implements IExpression {
                                str.append(", ");\r
                        }\r
                        // is the expression inside subscript always a constant?\r
-                       str.append(((Double)((Constant)subscripts[i]).value).intValue());\r
+                       Object sub = subscripts[i];\r
+                       if(sub instanceof Constant) {\r
+                               str.append(((Double)((Constant)sub).value).intValue());\r
+                       } else if (sub instanceof Variable) {\r
+                               str.append(((Variable)sub).base.name);\r
+                       }\r
                }\r
                str.append(']');\r
                return str.toString();\r
@@ -78,7 +91,6 @@ public class Variable implements IExpression {
        \r
        public int assignArray(IEnvironment env, int index, Array value, int asd) {\r
                for(int i=0;i<value.elements().size();i++) {\r
-//                     String s = name + "_" + (i+1);\r
                        Object element = value.element(i);\r
                        if(element instanceof Double) {\r
                                env.put(index+asd++, (Double)element);\r
@@ -94,8 +106,8 @@ public class Variable implements IExpression {
                return asd;\r
        }\r
        \r
-       public int index(IEnvironment env) {\r
-               return base.index + subscriptIndex(env);\r
+       public int index(IEnvironment env, IExpression[] subscripts) {\r
+               return base.index + subscriptIndex(env, subscripts);\r
        }\r
        \r
        public void setArrayIndex(IEnvironment environment, Array array, Object value) {\r
@@ -120,7 +132,7 @@ public class Variable implements IExpression {
                \r
        }\r
        \r
-       public Object getArrayIndex(IEnvironment environment, Array array) {\r
+       public Object getArrayIndex(IEnvironment environment, IExpression[] subscripts, Array array) {\r
                Object result = array;\r
                for(IExpression e : subscripts) {\r
                        int index = Utils.getIndex(e.evaluate(environment));\r
@@ -130,6 +142,8 @@ public class Variable implements IExpression {
                        IExpression exp = (IExpression)result;\r
                        return exp.evaluate(environment);\r
                }\r
+               if(result instanceof Array)\r
+                       throw new IllegalStateException();\r
                return result;\r
        }\r
 \r
@@ -137,12 +151,12 @@ public class Variable implements IExpression {
                env.put(base.index, value);\r
        }\r
        \r
-       public void assign(IEnvironment env, Object value) {\r
+       public void assign(IEnvironment env, IExpression[] subscripts, Object value) {\r
                if(value instanceof Array) {\r
                        if(base.isStoredAsArray()) {\r
-                               env.put(index(env), value);\r
+                               env.put(index(env, subscripts), value);\r
                        } else {\r
-                               assignArray(env, index(env), (Array)value, 0);\r
+                               assignArray(env, index(env, subscripts), (Array)value, 0);\r
                        }\r
                } else {\r
                        if(base.isStoredAsArray()) {\r
@@ -154,31 +168,77 @@ public class Variable implements IExpression {
                                }\r
                                setArrayIndex(env, existing, value);\r
                        } else {\r
-                               env.put(index(env), value);\r
+                               env.put(index(env, subscripts), value);\r
                        }\r
                }\r
        }\r
        \r
+       public int intoArray(IEnvironment env, int index, int d, Array target) {\r
+\r
+               if(d == base.dimensions.length-1) {\r
+                       for(int i=0;i<base.dimensions[d];i++) {\r
+                               target.addElement(env.getValue(index));\r
+                               index++;\r
+                       }\r
+                       return index;\r
+               }\r
+               \r
+               for(int i=0;i<base.dimensions[d];i++) {\r
+                       Array array = new Array();\r
+                       index = intoArray(env, index, d+1, array);\r
+                       target.addElement(array);\r
+               }\r
+               \r
+               return index;\r
+               \r
+       }\r
+       \r
        @Override\r
        public Object evaluate(IEnvironment environment) {\r
+               return evaluate(environment, subscripts);\r
+       }\r
+\r
+       public Object evaluate(IEnvironment environment, IExpression[] subscripts) {\r
                if(base.isStoredAsArray()) {\r
                        Array array = (Array)environment.getValue(base.index);\r
-                       if(hasScalarSubscript()) {\r
-                               Object o = getArrayIndex(environment, array);\r
+                       if(hasScalarSubscript(subscripts)) {\r
+                               Object o = getArrayIndex(environment, subscripts, array);\r
                                if(o instanceof Variable) throw new IllegalStateException();\r
+                               if(o instanceof Array)\r
+                                       throw new IllegalStateException();\r
                                return o;\r
                        }\r
                        else return array;\r
                } else {\r
-                       Object result = environment.getValue(index(environment)); \r
+                       \r
+                       if(base.dimension() > 1) {\r
+                               Array array = new Array();\r
+                               intoArray(environment, base.index, 0, array);\r
+                               return array;\r
+                       }\r
+                       \r
+                       Object result = environment.getNamedValue(base.name);\r
+                       if(result == null) result = environment.getValue(index(environment, subscripts));\r
                        if(result == null) throw new UnassignedVariableException("No value for " + base.name);\r
+                       \r
                        return result;\r
                }\r
        }\r
        \r
-       private boolean hasScalarSubscript() {\r
+       private boolean hasScalarSubscript(IExpression[] subscripts) {\r
                if(subscripts == null) return false;\r
                else return true;\r
        }\r
        \r
+       public Variable withBase(IFrame frame, String prefix) {\r
+               if(subscripts != null) {\r
+                       IExpression[] subscripts2 = new IExpression[subscripts.length];\r
+                       for(int i=0;i<subscripts.length;i++)\r
+                               subscripts2[i] = subscripts[i].withBase(frame, prefix);\r
+                       return new Variable(frame, prefix + base.name, subscripts2);\r
+               } else {\r
+                       return new Variable(frame, prefix + base.name,null);\r
+               }\r
+       }\r
+       \r
 }\r
index 4e64d7a9d44f848eba590764eff75e3707c2767c..c0719f9df5c4e417b3793a92152a92d0eef2ac6b 100644 (file)
@@ -10,6 +10,8 @@
  *******************************************************************************/\r
 package fi.semantum.sysdyn.solver;\r
 \r
+import java.util.Arrays;\r
+\r
 public class VariableBase {\r
        \r
        public String name;\r
@@ -22,6 +24,11 @@ public class VariableBase {
                this.name = name;\r
                this.index = index;\r
        }\r
+       public VariableBase(String name, int index, int[] dimensions) {\r
+               this.name = name;\r
+               this.index = index;\r
+               this.dimensions = dimensions;\r
+       }\r
        public void tellSubscripts(IExpression[] e) {\r
                if(e == null) return;\r
                if(dimensions == null) \r
@@ -48,4 +55,9 @@ public class VariableBase {
                for(int d : dimensions) if(d == -1) return true;\r
                return false;\r
        }\r
+       \r
+       VariableBase withBase(String prefix) {\r
+               return new VariableBase(prefix+name, index, dimensions);\r
+       }\r
+       \r
 }\r
index 02043c750eafd019fd8004925e2ef2f73abd5d4c..89d0f456c189209ac304c04c8adc303948a78263 100644 (file)
@@ -36,4 +36,9 @@ public class VariableDeclaration implements IExpression {
                throw new UnsupportedOperationException();\r
        }\r
        \r
+       @Override\r
+       public IExpression withBase(IFrame frame, String prefix) {\r
+               throw new UnsupportedOperationException();\r
+       }\r
+       \r
 }\r
index 793e0cfd48b297c90972d0c14f6775ff7b27f191..d95e0cdd4f9b02ea4b6609b6dbe95ec84be45c89 100644 (file)
@@ -119,7 +119,7 @@ void class_definition() : {
 //  class_specifier\r
     ( "encapsulated" )?\r
     ( "partial" )?\r
-    ( "class" | "model" | "record" | "block" | ( "expandable" )? "connector" | "type" |\r
+    ( "class" { jjtThis.op = "class"; } | "model" { jjtThis.op = "model"; } | "record" | "block" | ( "expandable" )? "connector" | "type" |\r
     "package" | "function" { jjtThis.op = "function"; } | "operator" | "operator function" | "operator record" )\r
     class_specifier()\r
 }\r
@@ -212,7 +212,7 @@ Node element() : {
     extends_clause() |\r
     ( "redeclare" )?\r
     ( "final" )?\r
-    ( "inner" )? ( "outer" )?\r
+    ( "inner" { jjtThis.op = "inner"; } )? ( "outer" { jjtThis.op = "outer"; } )?\r
     ( (class_definition() | component_clause()) |\r
         "replaceable" (class_definition() | component_clause())\r
         (constraining_clause() comment())?)\r
@@ -651,7 +651,7 @@ void term() : {
 \r
 void mul_op() : {\r
 } {\r
-    "*" { jjtThis.op = "*";} | "/" { jjtThis.op = "/";} | ".*" | "./"\r
+    "*" { jjtThis.op = "*";} | "/" { jjtThis.op = "/";} | ".*" { jjtThis.op = ".*";} | "./"\r
 }\r
 \r
 void factor() : {\r
@@ -717,7 +717,7 @@ void function_arguments() : {
 } {\r
        //expression [ "," function_arguments | for for_indices ]\r
        //| named_arguments\r
-        LOOKAHEAD(2) expression() ( "," function_arguments() | "for" for_indices() )?\r
+        LOOKAHEAD(2) expression() ( "," function_arguments() | "for" for_indices() { jjtThis.op = "for"; } )?\r
        | named_arguments()\r
 }\r
 \r
index da8f6ba4ac5cd28963ff2e9f8ba3280f337fc5cb..7908c7f93cf55d6e6a58048c9b78d65c436de913 100644 (file)
@@ -174,7 +174,7 @@ public class ModelicaManager {
         * \r
         * @return Open Modelica home directory\r
         */\r
-       private static File getOMHome() {\r
+       public static File getOMHome() {\r
                Preferences node = ConfigurationScope.INSTANCE.getNode(Activator.PLUGIN_ID);\r
                String omHomePath = node.get(OpenModelicaPreferences.OM_HOME, null);\r
                if (omHomePath != null) {\r
@@ -298,7 +298,7 @@ public class ModelicaManager {
                thread.run();\r
        }\r
 \r
-       public static SimulationLocation createSimulationLocation(File modelDir, String modelName, String modelContent) {               \r
+       public static SimulationLocation createSimulationLocation(File modelDir, String modelName, String modelContent, File omHome, boolean isOldOMVersion) {          \r
                if (!modelDir.isDirectory()) {\r
                        return null;\r
                }\r
@@ -323,7 +323,7 @@ public class ModelicaManager {
                }\r
                \r
                // full model files are (apparently) only needed for old parameter comparison routines\r
-               if (isOldOMVersion()) {\r
+               if (isOldOMVersion) {\r
                        location.fullModelDir = new File(location.getModelDir(), "fullModel");\r
                        if (!location.fullModelDir.isDirectory()) {\r
                                location.fullModelDir.mkdir();\r
@@ -332,7 +332,7 @@ public class ModelicaManager {
                        location.fullModelScriptFile = new File(location.fullModelDir, location.getModelName() + "_full.mos");\r
                }\r
                \r
-               location.omHome = getOMHome();\r
+               location.omHome = omHome;\r
                \r
                return location;\r
        }\r
index 87d62c8b3e63b09b0f4eb63a9f91591402899b10..5958ee17a9aba9de27b2162a405c2b35ff750d67 100644 (file)
@@ -382,7 +382,7 @@ public class OldSysdynExperiment extends SysdynExperiment {
         FunctionUtils.updateFunctionFilesForExperiment(this);\r
 \r
 \r
-        SimulationLocation location = ModelicaManager.createSimulationLocation(simulationDir, sysdynModel.getConfiguration().getLabel(), modelText);\r
+        SimulationLocation location = ModelicaManager.createSimulationLocation(simulationDir, sysdynModel.getConfiguration().getLabel(), modelText, ModelicaManager.getOMHome(), ModelicaManager.isOldOMVersion());\r
         if (fmu) {\r
                ModelicaManager.createFMUSimulationScripts(location, inits, additionalScript);\r
         }\r
diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynExperiments.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynExperiments.java
new file mode 100644 (file)
index 0000000..acbfdb5
--- /dev/null
@@ -0,0 +1,122 @@
+package org.simantics.sysdyn.manager;\r
+\r
+import java.util.concurrent.Semaphore;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.NullProgressMonitor;\r
+import org.eclipse.core.runtime.SubMonitor;\r
+import org.simantics.Simantics;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.project.IProject;\r
+import org.simantics.simulation.experiment.ExperimentState;\r
+import org.simantics.simulation.experiment.IDynamicExperiment;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.model.ExperimentLoadingFailed;\r
+import org.simantics.simulation.project.IExperimentActivationListener;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.utils.DataContainer;\r
+\r
+public class SysdynExperiments {\r
+\r
+    public static String activateExperiment(IProgressMonitor monitor, final IProject project, final IExperimentManager manager, final Resource experimentResource) {\r
+       \r
+       if(monitor == null) monitor = new NullProgressMonitor();\r
+       \r
+        final SubMonitor mon = SubMonitor.convert(monitor, "Activating experiment", 100000);\r
+\r
+//        SysdynExperimentManagerListener.listenManager(manager);\r
+        IExperiment[] experiments = manager.getExperiments();\r
+        SubMonitor shutdownMon = mon.newChild(10000);\r
+        int workPerExperiment;\r
+        if (experiments.length > 0)\r
+               workPerExperiment = 10000 / experiments.length;\r
+        else\r
+               workPerExperiment = 10000;\r
+        for(IExperiment e : experiments)\r
+            if(e.getState() != ExperimentState.DISPOSED)\r
+                e.shutdown(shutdownMon.newChild(workPerExperiment));\r
+        mon.setWorkRemaining(90000);\r
+\r
+        final Semaphore activated = new Semaphore(0);\r
+        final DataContainer<Throwable> problem = new DataContainer<Throwable>();\r
+        final DataContainer<IExperiment> run = new DataContainer<IExperiment>();\r
+        manager.startExperiment(experimentResource, new IExperimentActivationListener() {\r
+\r
+            @Override\r
+            public void onExperimentActivated(final IExperiment experiment) {\r
+//                MessageService.defaultLog(new org.eclipse.core.runtime.Status(IStatus.INFO, "org.simantics.simulation.ui", 0, "Activated experiment " + experiment.getIdentifier() , null));\r
+                activated.release();\r
+                run.set(experiment);\r
+            }\r
+            @Override\r
+            public void onFailure(Throwable e) {\r
+                problem.set(e);\r
+                activated.release();\r
+            }\r
+            @Override\r
+            public void onMessage(IStatus message) {\r
+//                MessageService.getDefault().log(message);\r
+            }\r
+            @Override\r
+            public IProgressMonitor getProgressMonitor() {\r
+                return mon;\r
+            }\r
+        }, true);\r
+        try {\r
+            activated.acquire();\r
+            Throwable t = problem.get();\r
+            if (t != null) {\r
+                if (t instanceof ExperimentLoadingFailed) {\r
+//                    ErrorLogger.defaultLogError(t);\r
+//                    ShowMessage.showError("Experiment Activation Failed", t.getMessage());\r
+                } else {\r
+//                    ExceptionUtils.logAndShowError(t);\r
+                }\r
+            }\r
+\r
+            return run.get().getIdentifier();\r
+            //return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Experiment activation failed, see exception for details.", problem.get());\r
+        } catch (InterruptedException e) {\r
+            return null;\r
+        }\r
+    }\r
+       \r
+    \r
+    public static String activateExperiment(Resource experiment) throws DatabaseException {\r
+\r
+//     Resource experiment = Layer0Utils.getPossibleChild(graph, model, name);\r
+//     if( experiment == null) return false;\r
+\r
+//     SimulationResource SIMU = SimulationResource.getInstance(graph);\r
+//        if (!graph.isInstanceOf(experiment, SIMU.Experiment)) return false;\r
+        \r
+        final IProject project = Simantics.getProject();\r
+        if (project == null) return null;\r
\r
+        final IExperimentManager experimentManager = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+        if(experimentManager == null) return null;\r
+        \r
+       return SysdynExperiments.activateExperiment(null, project, experimentManager, experiment);\r
+               \r
+       }\r
+    \r
+    public static void run(String experimentId) throws DatabaseException {\r
+\r
+        final IProject project = Simantics.getProject();\r
+        if (project == null) return;\r
\r
+        final IExperimentManager experimentManager = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+        if(experimentManager == null) return;\r
+        \r
+        IExperiment experiment = experimentManager.getExperiment(experimentId);\r
+        if(experiment instanceof IDynamicExperiment)\r
+               ((IDynamicExperiment)experiment).simulate(true);\r
+        \r
+    }\r
+    \r
+\r
+    \r
+    \r
+}\r
index 4c00a72e0115f14d02e47945516bb0a2dc2fb88d..7144a00c3a7b4db0718882145a91f72ab3d7e76c 100644 (file)
@@ -1,5 +1,6 @@
 package org.simantics.sysdyn.solver;\r
 \r
+import java.io.File;\r
 import java.util.HashMap;\r
 \r
 import org.simantics.modelica.ModelicaManager;\r
@@ -11,11 +12,14 @@ import org.simantics.sysdyn.manager.SysdynModel;
 import org.simantics.sysdyn.modelica.ModelicaWriter;\r
 import org.simantics.sysdyn.representation.Model;\r
 import org.simantics.sysdyn.solver.SolverSettings.SolverType;\r
+import org.simantics.utils.FileUtils;\r
 \r
 import fi.semantum.sysdyn.solver.Solver;\r
 \r
 public class InternalSolver implements ISolver {\r
 \r
+       public static final boolean PRINT_CODE = false;\r
+       \r
        private SysdynExperiment experiment;\r
        private SysdynModel model;\r
        private ISolverMonitor monitor;\r
@@ -46,14 +50,14 @@ public class InternalSolver implements ISolver {
 \r
        @Override\r
        public void initialize() throws Exception {\r
-               String omVersion = ModelicaManager.getDefaultOMVersion();\r
-               String modelContent = ModelicaWriter.write(model.getModules(), false, omVersion);\r
+//             String omVersion = ModelicaManager.getDefaultOMVersion();\r
+               String modelContent = ModelicaWriter.write(model.getModules(), false, "1.9");\r
 \r
                // update some stuff\r
                FunctionUtils.updateFunctionFilesForExperiment(experiment);\r
 \r
                location = ModelicaManager.createSimulationLocation(experiment.getExperimentDir(), \r
-                               model.getConfiguration().getLabel(), modelContent);\r
+                               model.getConfiguration().getLabel(), modelContent, null, false);\r
                \r
                // set solver parameters\r
                Model representation = model.getConfiguration().getModel();\r
@@ -80,12 +84,34 @@ public class InternalSolver implements ISolver {
 \r
        @Override\r
        public void buildModel() throws Exception {\r
-               String flat = ModelicaManager.getFlatModelText(location, monitor, FunctionUtils.getLibraryPathsForModelica(experiment));\r
-               solver.prepare(flat);\r
+               \r
+//             String flat = ModelicaManager.getFlatModelText(location, monitor, FunctionUtils.getLibraryPathsForModelica(experiment));\r
+//             System.err.println("=== FLAT ===");\r
+//             System.err.println(flat);\r
+//             System.err.println("=== FLAT ENDS ===");\r
+               \r
+               StringBuilder code = new StringBuilder();\r
+               for(String path : FunctionUtils.getLibraryPathsForModelica(experiment)) {\r
+                       File f = new File(location.modelFile.getParentFile(), path);\r
+                       code.append(FileUtils.getContents(f));\r
+               }\r
+               code.append(FileUtils.getContents(location.modelFile));\r
+               \r
+               if(PRINT_CODE) {\r
+                       System.err.println("=== CODE === ");\r
+                       System.err.println(code.toString());\r
+                       System.err.println("=== CODE ENDS ===");\r
+               }\r
+\r
+               solver.prepare(code.toString());\r
+               \r
        }\r
 \r
        @Override\r
        public void runSolver() throws Exception {\r
+               \r
+               long startTime = System.nanoTime();\r
+               \r
                // the number of result intervals in the simulation (account for initial values)\r
                int count = (int)((stop - start) / interval) + 1;\r
                // the number of steps in one result interval\r
@@ -94,13 +120,22 @@ public class InternalSolver implements ISolver {
                // an array containing an accurate time stamp for each interval\r
                double[] times = new double[count];\r
                // a map containing values of all variables for each interval\r
-               HashMap<String, double[]> values = new HashMap<String, double[]>();\r
+\r
+               String[] keys = solver.keys();\r
+\r
+               double[][] values = new double[keys.length][];\r
+               \r
+//             HashMap<String, double[]> values = new HashMap<String, double[]>();\r
                // initialize the temporary data structures\r
                times[0] = start;\r
-               HashMap<String, Double> tmp = solver.values();\r
-               for (String key : tmp.keySet()) {\r
-                       values.put(key, new double[count]);\r
-                       values.get(key)[0] = tmp.get(key);\r
+               \r
+               double[] valueArray = solver.values();\r
+//             HashMap<String, Double> tmp = solver.values();\r
+//             String[] keys = new ArrayList<String>(tmp.keySet()).toArray(new String[tmp.size()]);\r
+\r
+               for(int i=0;i<keys.length;i++) {\r
+                       values[i] = new double[count];\r
+                       values[i][0] = valueArray[i];\r
                }\r
                \r
                // run the simulation\r
@@ -109,16 +144,29 @@ public class InternalSolver implements ISolver {
                                solver.step();\r
                        }\r
                        times[interval] = times[interval-1] + steps * step;\r
-                       tmp = solver.values();\r
-                       for (String key : tmp.keySet()) {\r
-                               values.get(key)[interval] = tmp.get(key);\r
+\r
+                       valueArray = solver.values();\r
+                       for(int i=0;i<keys.length;i++) {\r
+                               values[i][interval] = valueArray[i];\r
                        }\r
+                       \r
                }\r
 \r
                results = new HashMap<String, SysdynDataSet>();\r
-               for (String name : values.keySet()) {\r
-                       results.put(name, new SysdynDataSet(name, null, times, values.get(name)));\r
+               for(int i=0;i<keys.length;i++) {\r
+                       String name = keys[i];\r
+                       double[] arr = values[i];\r
+                       results.put(name, new SysdynDataSet(name, null, times, arr));\r
                }\r
+\r
+//             for (String name : values.keySet()) {\r
+//                     results.put(name, new SysdynDataSet(name, null, times, values.get(name)));\r
+//             }\r
+               \r
+               long endTime = System.nanoTime();\r
+               \r
+               System.err.println("ran simulation in " + 1e-6*(endTime-startTime) + "ms.");\r
+               \r
        }\r
 \r
        @Override\r
index 9c80432225862ad319dcfb7ff6c9e42c1b38f3b7..e12c6e3d97d019adb7b59331e35240e5bfbc72c0 100644 (file)
@@ -21,12 +21,14 @@ public class SysdynSimulationJob extends Job {
        protected String name;\r
        protected SysdynExperiment experiment;\r
        protected ISolver solver;\r
+       protected ISolverMonitor solverMonitor;\r
 \r
        public SysdynSimulationJob(String name, SysdynExperiment experiment) {\r
                super(name);\r
                this.name = name;\r
                this.experiment = experiment;\r
                this.solver = null;\r
+               this.solverMonitor = SysdynConsole.INSTANCE;\r
        }\r
 \r
        @Override\r
@@ -60,7 +62,7 @@ public class SysdynSimulationJob extends Job {
                // has changed, a new solver must be created\r
                if (solver == null || !solver.getType().equals(type)) {\r
                        if (SolverType.INTERNAL.equals(type)) {\r
-                               solver = new InternalSolver(experiment, experiment.sysdynModel, SysdynConsole.INSTANCE);\r
+                               solver = new InternalSolver(experiment, experiment.sysdynModel, solverMonitor);\r
                        }\r
                        else if (SolverType.OPENMODELICA.equals(type)) {\r
                                return new Status(Status.ERROR, pluginId, "The experiment should be reloaded");\r