From: villberg Date: Mon, 31 Mar 2014 06:39:39 +0000 (+0000) Subject: Getting closer X-Git-Tag: 1.8.1~98 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=3f881b5daf4a479d9dc52f143bdd63653248a9de;p=simantics%2Fsysdyn.git Getting closer refs #4765 git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@29215 ac1ea38d-2e2b-0410-8846-a27921b304fc --- diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Addition.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Addition.java index 5e303397..27ee6841 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Addition.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Addition.java @@ -10,6 +10,10 @@ *******************************************************************************/ package fi.semantum.sysdyn.solver; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; + public class Addition implements IExpression { public IExpression exp1; @@ -27,9 +31,17 @@ public class Addition implements IExpression { @Override public Object evaluate(IEnvironment environment) { - Double d1 = (Double)exp1.evaluate(environment); - Double d2 = (Double)exp2.evaluate(environment); - return d1 + d2; + Object o1 = exp1.evaluate(environment); + Object o2 = exp2.evaluate(environment); + if(o1 instanceof Double && o2 instanceof Double) { + return (Double)o1 + (Double)o2; + } + if(o1 instanceof Array && o2 instanceof Array) { + Array la = (Array)o1; + Array ra = (Array)o2; + return la.add(ra); + } + throw new IllegalStateException(); } @Override @@ -37,4 +49,16 @@ public class Addition implements IExpression { return new Addition(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix)); } + @Override + public Object getPossibleConstant() { + return null; + } + + @Override + public IExpression rewrite(IFrame frame, Map copies) { + exp1 = exp1.rewrite(frame, copies); + exp2 = exp2.rewrite(frame, copies); + return this; + } + } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/And.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/And.java index 18f3f158..d77a191c 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/And.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/And.java @@ -11,22 +11,23 @@ package fi.semantum.sysdyn.solver; import java.util.ArrayList; +import java.util.Map; public class And implements IExpression { - public ArrayList exps; + public IExpression[] exps; public And(ArrayList exps) { - this.exps = exps; + this.exps = exps.toArray(new IExpression[exps.size()]); } @Override public String toString() { StringBuilder b = new StringBuilder(); - b.append(exps.get(0)); - for(int i=1;i copies) { + for(int i=0;i copies) { + args = args.rewrite(frame, copies); + return this; + } } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Argument.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Argument.java index cbe534d0..3a7013f4 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Argument.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Argument.java @@ -10,6 +10,8 @@ *******************************************************************************/ package fi.semantum.sysdyn.solver; +import java.util.Map; + public class Argument implements IExpression { public String name; @@ -32,7 +34,17 @@ public class Argument implements IExpression { @Override public IExpression withBase(IFrame frame, String prefix) { - return new Argument(name, modification.withBase(frame, prefix)); + return new Argument(prefix+name, modification.withBase(frame, prefix)); + } + + @Override + public Object getPossibleConstant() { + return null; + } + + public Argument rewrite(IFrame frame, Map copies) { + modification = modification.rewrite(frame, copies); + return this; } } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ArgumentList.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ArgumentList.java index f2e637ad..02d4d439 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ArgumentList.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ArgumentList.java @@ -11,35 +11,36 @@ package fi.semantum.sysdyn.solver; import java.util.ArrayList; +import java.util.Map; public class ArgumentList { - public ArrayList args; + public Argument[] args; public String op; public ArgumentList(ArrayList args) { - this.args = args; + this.args = args.toArray(new Argument[args.size()]); this.op = ""; } public ArgumentList(ArrayList args, String op) { - this.args = args; + this.args = args.toArray(new Argument[args.size()]); this.op = op; } public ArgumentList(String op) { - this.args = new ArrayList(); + this.args = new Argument[0]; this.op = op; } @Override public String toString() { - if(args.size() == 0) return "()"; + if(args.length == 0) return "()"; StringBuilder b = new StringBuilder(); - b.append("(" + args.get(0)); - for(int i=1;i copies) { + for(int i=0;i copies) { + for(int i=0;i lae = elements(); + Collection rae = other.elements(); + if(lae.size() != rae.size()) throw new IllegalStateException(); + Iterator li = lae.iterator(); + Iterator ri = rae.iterator(); + for(int i=0;i lae = elements(); + Collection rae = other.elements(); + if(lae.size() != rae.size()) throw new IllegalStateException(); + Iterator li = lae.iterator(); + Iterator ri = rae.iterator(); + for(int i=0;i copies) { + start = start.rewrite(frame, copies); + end = end.rewrite(frame, copies); + return this; + } } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Constant.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Constant.java index 56bd8b64..d00f2362 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Constant.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Constant.java @@ -10,6 +10,8 @@ *******************************************************************************/ package fi.semantum.sysdyn.solver; +import java.util.Map; + public class Constant implements IExpression { public Object value; @@ -36,6 +38,16 @@ public class Constant implements IExpression { public IExpression withBase(IFrame frame, String prefix) { return this; } + + @Override + public Object getPossibleConstant() { + return null; + } + + @Override + public IExpression rewrite(IFrame frame, Map copies) { + return this; + } } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Declaration.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Declaration.java index 2ef7fd73..a1490f52 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Declaration.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Declaration.java @@ -11,6 +11,8 @@ *******************************************************************************/ package fi.semantum.sysdyn.solver; +import java.util.Map; + public class Declaration implements IExpression { public Variable variable; @@ -35,5 +37,15 @@ public class Declaration implements IExpression { public IExpression withBase(IFrame frame, String prefix) { throw new UnsupportedOperationException(); } + + @Override + public Object getPossibleConstant() { + return null; + } + + @Override + public IExpression rewrite(IFrame frame, Map copies) { + throw new UnsupportedOperationException(); + } } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Derivate.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Derivate.java index b67074e8..426e3fa7 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Derivate.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Derivate.java @@ -10,6 +10,8 @@ *******************************************************************************/ package fi.semantum.sysdyn.solver; +import java.util.Map; + public class Derivate implements IExpression { private Variable variable; @@ -26,7 +28,7 @@ public class Derivate implements IExpression { public Object evaluate(IEnvironment _environment) { Environment environment = (Environment)_environment; // Double old = (Double)environment.getValue(variable.name + variable.subscriptKey()); - Double old = (Double)environment.getValue(variable.index(_environment, subscripts)); + Double old = (Double)environment.getValue(variable.base.index(_environment, subscripts)); return old+environment.step*(Double)e.evaluate(environment); } @@ -46,5 +48,20 @@ public class Derivate implements IExpression { return new Derivate((Variable)variable.withBase(frame, prefix), null, e.withBase(frame, prefix)); } } + + @Override + public Object getPossibleConstant() { + return null; + } + + @Override + public IExpression rewrite(IFrame frame, Map copies) { + if(subscripts != null) { + for(int i=0;i copies) { + throw new UnsupportedOperationException(); + } } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Division.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Division.java index 2d31b107..0f643949 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Division.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Division.java @@ -10,6 +10,8 @@ *******************************************************************************/ package fi.semantum.sysdyn.solver; +import java.util.Map; + public class Division implements IExpression { public IExpression exp1; @@ -51,5 +53,17 @@ public class Division implements IExpression { public IExpression withBase(IFrame frame, String prefix) { return new Division(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix)); } + + @Override + public Object getPossibleConstant() { + return null; + } + @Override + public IExpression rewrite(IFrame frame, Map copies) { + exp1 = exp1.rewrite(frame, copies); + exp2 = exp2.rewrite(frame, copies); + return this; + } + } 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 index c2b9a5f6..d8d3aafb 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ElementwiseProduct.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ElementwiseProduct.java @@ -12,6 +12,7 @@ package fi.semantum.sysdyn.solver; import java.util.Collection; import java.util.Iterator; +import java.util.Map; public class ElementwiseProduct implements IExpression { @@ -54,5 +55,17 @@ public class ElementwiseProduct implements IExpression { public IExpression withBase(IFrame frame, String prefix) { return new ElementwiseProduct(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix)); } + + @Override + public Object getPossibleConstant() { + return null; + } + @Override + public IExpression rewrite(IFrame frame, Map copies) { + exp1 = exp1.rewrite(frame, copies); + exp2 = exp2.rewrite(frame, copies); + return this; + } + } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/EnumElementsVariableBase.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/EnumElementsVariableBase.java new file mode 100644 index 00000000..d80d5dfd --- /dev/null +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/EnumElementsVariableBase.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2013 VTT Technical Research Centre of Finland. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +public class EnumElementsVariableBase extends VariableBase { + + private Array result; + + public EnumElementsVariableBase(Model clazz) { + super("elements"); + result = new Array(); + for(VariableDeclaration vd : clazz.variables) { + Constant c = (Constant)vd.modification.args[0].modification; + result.addElement(c.value); + } + } + + public EnumElementsVariableBase(String name, Array result) { + super(name); + this.result = result; + } + + @Override + public Object evaluate(IEnvironment environment, IExpression[] subscripts) { + return result; + } + + @Override + VariableBase withBase(String prefix) { + return new EnumElementsVariableBase(prefix+name, result); + } + + @Override + public IExpression getPossibleConstant() { + return result; + } + +} diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/EnumSizeVariableBase.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/EnumSizeVariableBase.java new file mode 100644 index 00000000..6ed388f0 --- /dev/null +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/EnumSizeVariableBase.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2013 VTT Technical Research Centre of Finland. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +public class EnumSizeVariableBase extends VariableBase { + + private Double value; + + public EnumSizeVariableBase(Model clazz) { + super("size"); + value = (double)clazz.variables.size(); + } + + public EnumSizeVariableBase(String name, double value) { + super(name); + this.value = value; + } + + @Override + public Object evaluate(IEnvironment environment, IExpression[] subscripts) { + return value; + } + + @Override + VariableBase withBase(String prefix) { + return new EnumSizeVariableBase(prefix+name, value); + } + + @Override + public IExpression getPossibleConstant() { + return new Constant(value.toString()); + } + +} diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Environment.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Environment.java index 6ab0d2fd..1e147408 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Environment.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Environment.java @@ -12,7 +12,9 @@ package fi.semantum.sysdyn.solver; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import java.util.TreeMap; @@ -85,14 +87,40 @@ final public class Environment implements IEnvironment, ISystem { }); model.functions.put("zidz", new Fn1(2) { - @Override - public Object evaluate(IEnvironment environment, int argc) { - Double p1 = (Double)environment.getValue(0); - Double p2 = (Double)environment.getValue(1); + private Object evaluate(Double p1, Double p2) { if(Math.abs(p2) < 1e-12) return 0.0; else return p1 / p2; } + @Override + public Object evaluate(IEnvironment environment, int argc) { + Object o1 = environment.getValue(0); + Object o2 = environment.getValue(1); + + if(o1 instanceof Double && o2 instanceof Double) { + return evaluate((Double)o1, (Double)o2); + } + if(o1 instanceof Array && o2 instanceof Array) { + Array la = (Array)o1; + Array ra = (Array)o2; + Collection lae = la.elements(); + Collection rae = ra.elements(); + if(lae.size() != rae.size()) throw new UnsupportedOperationException(); + Iterator li = lae.iterator(); + Iterator ri = rae.iterator(); + Array result = new Array(); + for(int i=0;i getHistory(String ident) { @@ -316,26 +368,56 @@ final public class Environment implements IEnvironment, ISystem { double[] valueArray; + public void addIndexed(int dimensions[], ArrayList keys, String prefix, int d) { + + if(d == dimensions.length) { + keys.add(prefix); + return; + } + + for(int i=0;i keys) { + +// int dimensions[] = base.dimensions; + if(dimensions == null) { + keys.add(name); + } else { + addIndexed(dimensions, keys, name, 0); + } + + } + + public void addVariable(Variable var, ArrayList keys) { + addVariable(var.base.name, var.base.dimensions, keys); + } + public String[] getValueKeyArray() { ArrayList keys = new ArrayList(); for (int i = 0; i < model.assignmentArray.length; i++) { - Variable v = model.assignmentArray[i].target; - keys.add(v.toString()); + addVariable(model.assignmentArray[i].target, keys); } for (int i = 0; i < model.derivativeArray.length; i++) { - Variable v = model.derivativeArray[i].target; - keys.add(v.toString()); + addVariable(model.derivativeArray[i].target, keys); } // NOTE: there is room for optimization as parameter values that do not // change should only be obtained once (and parameter values that do // change are (possibly) included in assignments or derivatives) for(int i = 0; i < model.parameterArray.length; i++) { - Variable v = model.parameterArray[i].variable; - keys.add(v.toString()); + addVariable(model.parameterArray[i].variable, keys); + } + + for(Map.Entry entry : model.copies.entrySet()) { + addVariable(entry.getKey(), entry.getValue().dimensions, keys); } valueArray = new double[keys.size()]; @@ -351,12 +433,14 @@ final public class Environment implements IEnvironment, ISystem { for (int i = 0; i < model.assignmentArray.length; i++) { Variable v = model.assignmentArray[i].target; - valueArray[offset++] = (Double)getValue(v.index(this, null)); + for(int index=0;index entry : model.copies.entrySet()) { + VariableBase base = entry.getValue(); + for(int index=0;index copies) { + exp1 = exp1.rewrite(frame, copies); + exp2 = exp2.rewrite(frame, copies); + return this; + } } 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 index 550d7ce9..1f66818a 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ForArray.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/ForArray.java @@ -12,6 +12,7 @@ package fi.semantum.sysdyn.solver; import java.util.ArrayList; import java.util.Collection; +import java.util.Map; public class ForArray implements IExpression { @@ -20,7 +21,11 @@ public class ForArray implements IExpression { public ForArray() { } - + + public ForArray(ArrayList elements) { + this.elements = elements; + } + public void addElement(Object element) { if(element instanceof Constant) addElement(((Constant)element).value); else elements.add(element); @@ -78,7 +83,31 @@ public class ForArray implements IExpression { @Override public IExpression withBase(IFrame frame, String prefix) { - throw new UnsupportedOperationException(); + ArrayList e = new ArrayList(); + for(Object o : elements) { + if(o instanceof IExpression) { + e.add(((IExpression)o).withBase(frame, prefix)); + } else { + e.add(o); + } + } + return new ForArray(e); + } + + @Override + public Object getPossibleConstant() { + return null; + } + + @Override + public IExpression rewrite(IFrame frame, Map copies) { + for(int i=0;i copies) { + exp1 = exp1.rewrite(frame, copies); + exp2 = exp2.rewrite(frame, copies); + return this; + } + } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/GreaterThan.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/GreaterThan.java index 9f3244ea..21d81acc 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/GreaterThan.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/GreaterThan.java @@ -10,6 +10,8 @@ *******************************************************************************/ package fi.semantum.sysdyn.solver; +import java.util.Map; + public class GreaterThan implements IExpression { public IExpression exp1; @@ -34,5 +36,17 @@ public class GreaterThan implements IExpression { public IExpression withBase(IFrame frame, String prefix) { return new GreaterThan(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix)); } - + + @Override + public Object getPossibleConstant() { + return null; + } + + @Override + public IExpression rewrite(IFrame frame, Map copies) { + exp1 = exp1.rewrite(frame, copies); + exp2 = exp2.rewrite(frame, copies); + return this; + } + } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IExpression.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IExpression.java index 942b7a3a..6377a3ad 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IExpression.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IExpression.java @@ -10,9 +10,13 @@ *******************************************************************************/ package fi.semantum.sysdyn.solver; +import java.util.Map; + public interface IExpression { public Object evaluate(IEnvironment environment); public IExpression withBase(IFrame frame, String prefix); + public Object getPossibleConstant(); + public IExpression rewrite(IFrame frame, Map copies); } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IFrame.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IFrame.java index 7edb1414..805ef557 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IFrame.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IFrame.java @@ -12,4 +12,6 @@ package fi.semantum.sysdyn.solver; public interface IFrame { public VariableBase getBase(String name); + public VariableBase getBase(VariableBase base, String prefix); + public Model getClass(String name); } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IfThenElse.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IfThenElse.java index ba4bd801..2176faf4 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IfThenElse.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/IfThenElse.java @@ -10,6 +10,8 @@ *******************************************************************************/ package fi.semantum.sysdyn.solver; +import java.util.Map; + public class IfThenElse implements IExpression { public IExpression exp; @@ -40,5 +42,18 @@ public class IfThenElse implements IExpression { public IExpression withBase(IFrame frame, String prefix) { return new IfThenElse(exp.withBase(frame, prefix), t.withBase(frame, prefix), e.withBase(frame, prefix)); } - + + @Override + public Object getPossibleConstant() { + return null; + } + + @Override + public IExpression rewrite(IFrame frame, Map copies) { + exp = exp.rewrite(frame, copies); + t = t.rewrite(frame, copies); + e = e.rewrite(frame, copies); + return this; + } + } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LessOrEqualThan.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LessOrEqualThan.java index a1fbc884..7c2f2870 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LessOrEqualThan.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LessOrEqualThan.java @@ -10,6 +10,8 @@ *******************************************************************************/ package fi.semantum.sysdyn.solver; +import java.util.Map; + public class LessOrEqualThan implements IExpression { public IExpression exp1; @@ -37,4 +39,16 @@ public class LessOrEqualThan implements IExpression { return new LessOrEqualThan(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix)); } + @Override + public Object getPossibleConstant() { + return null; + } + + @Override + public IExpression rewrite(IFrame frame, Map copies) { + exp1 = exp1.rewrite(frame, copies); + exp2 = exp2.rewrite(frame, copies); + return this; + } + } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LessThan.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LessThan.java index 4684ab52..9a808538 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LessThan.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LessThan.java @@ -10,6 +10,8 @@ *******************************************************************************/ package fi.semantum.sysdyn.solver; +import java.util.Map; + public class LessThan implements IExpression { public IExpression exp1; @@ -36,5 +38,17 @@ public class LessThan implements IExpression { public IExpression withBase(IFrame frame, String prefix) { return new LessThan(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix)); } - + + @Override + public Object getPossibleConstant() { + return null; + } + + @Override + public IExpression rewrite(IFrame frame, Map copies) { + exp1 = exp1.rewrite(frame, copies); + exp2 = exp2.rewrite(frame, copies); + return this; + } + } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LineReader.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LineReader.java index 81ecabc4..d4e2f420 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LineReader.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/LineReader.java @@ -39,7 +39,7 @@ public class LineReader { public LineReader(String input, NodeCache cache) { chars = input.toCharArray(); this.cache = cache; - model = new Model(new Globals()); + model = new Model(new Globals(), "", false); parser = new Parser(); } @@ -90,7 +90,6 @@ public class LineReader { cache.store(line, (SimpleNode)node); } - parser.currentFrame = model; parser.walk((SimpleNode)node, 0, model); } @@ -119,7 +118,6 @@ public class LineReader { cache.store(line, (SimpleNode)node); } - parser.currentFrame = model; parser.walk((SimpleNode)node, 0, model); } @@ -143,7 +141,6 @@ public class LineReader { cache.store(line, (SimpleNode)node); } - parser.currentFrame = model; parser.walk((SimpleNode)node, 0, model); } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Model.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Model.java index 11dd7247..4aa58463 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Model.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Model.java @@ -14,6 +14,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import java.util.TreeMap; class Model implements IFrame { @@ -30,6 +31,7 @@ class Model implements IFrame { public ArrayList parameters = new ArrayList(); public ArrayList variables = new ArrayList(); public Map functions = new HashMap(); + public Map copies; public Assignment[] assignmentArray; public Assignment[] derivativeArray; @@ -37,8 +39,17 @@ class Model implements IFrame { public final Globals globals; - public Model(Globals globals) { + public String name; + public boolean isEnumClass; + + public Model(Globals globals, String name, boolean isEnumClass) { this.globals = globals; + this.name = name; + this.isEnumClass = isEnumClass; + } + + public void addVariable(VariableDeclaration vd) { + this.variables.add(vd); } public Fn getFunction(String name) { @@ -47,10 +58,24 @@ class Model implements IFrame { public HashMap names = new HashMap(); + public VariableBase getBase(VariableBase original, String prefix) { + VariableBase base = names.get(prefix+original.name); + if(base != null) return base; + base = original.withBase(prefix); + names.put(base.name, base); + return base; + } + public VariableBase getBase(String name) { VariableBase base = names.get(name); if(base == null) { - base = new VariableBase(name); + + if(isEnumClass) { + if("size".equals(name)) base = new EnumSizeVariableBase(this); + else if("elements".equals(name)) base = new EnumElementsVariableBase(this); + } + + if(base == null) base = new VariableBase(name); names.put(name, base); } return base; @@ -68,14 +93,14 @@ class Model implements IFrame { Frame frame = new Frame(environment, fn.offset()); ArrayList argh = new ArrayList(); - argh.add(args.args.get(0).modification.toString()); - for(int i=0;i argh = new ArrayList(); - for(int i=0;i work, VariableBase target) { + VariableBase deep = work.get(target.name); + if(deep == null) return target; + return resolveCopy(work, target); + } + + private void rewrite() { + + ArrayList parameterCopies = new ArrayList(); + ArrayList variableCopies = new ArrayList(); + + HashMap work = new HashMap(); + + for(ParameterDeclaration pd : parameters) { + if(pd.modification instanceof Variable) { + Variable var = (Variable)pd.modification; + if(!SolverUtils.isFullSubscript(var.subscripts)) continue; + if(!SolverUtils.isFullSubscript(pd.variable.subscripts)) continue; + parameterCopies.add(pd); + work.put(pd.variable.base.name, var.base); + } + } + for(Assignment ass : assignments) { + if(ass.expression instanceof Variable) { + Variable var = (Variable)ass.expression; + if(!SolverUtils.isFullSubscript(var.subscripts)) continue; + if(!SolverUtils.isFullSubscript(ass.target.subscripts)) continue; + variableCopies.add(ass); + work.put(ass.target.base.name, var.base); + } + } + + parameters.removeAll(parameterCopies); + assignments.removeAll(variableCopies); + + copies = new TreeMap(); + for(String key : work.keySet()) { + VariableBase b = resolveCopy(work, work.get(key)); + copies.put(key, b); + } + + for(VariableDeclaration vd : variables) { + vd.modification = vd.modification.rewrite(this, copies); + vd.variable = (Variable)vd.variable.rewrite(this, copies); + } + for(ParameterDeclaration pd : parameters) { + pd.modification = pd.modification.rewrite(this, copies); + } + for(Assignment ass : assignments) { + ass.expression = ass.expression.rewrite(this, copies); + } + for(Assignment ass : derivatives) { + ass.expression = ass.expression.rewrite(this, copies); + } + for(Assignment ass : initials) { + ass.expression = ass.expression.rewrite(this, copies); + } + + } + public int prepare() { if(PRINT) { @@ -123,19 +209,32 @@ class Model implements IFrame { System.err.println("=================="); } - for(VariableDeclaration vd : variables) { - vd.variable.base.tellSubscripts(vd.variable.subscripts); - } - for(ParameterDeclaration pd : parameters) { - pd.variable.base.tellSubscripts(pd.variable.subscripts); + rewrite(); + + boolean done = true; + + for(int i=0;i<50;i++) { + done = true; + for(VariableDeclaration vd : variables) { + done &= vd.variable.base.tellSubscripts(vd.variable.subscripts, null); + } + for(ParameterDeclaration pd : parameters) { + done &= pd.variable.base.tellSubscripts(pd.variable.subscripts, pd.modification); + } + if(done) break; } + + if(!done) throw new IllegalStateException(); + int nextIndex = 0; for(Map.Entry entry : names.entrySet()) { VariableBase base = entry.getValue(); base.index = nextIndex; if(PRINT) System.err.println("Variable: " + entry.getKey() + " " + base.index + " " + Arrays.toString(base.dimensions)); - nextIndex += base.dimension(); + int dim = base.dimension(); + if(dim == -1) dim = 1; + nextIndex += dim; } if(PRINT) @@ -174,4 +273,65 @@ class Model implements IFrame { } + @Override + public Model getClass(String name) { + return globals.classes.get(name); + } + + public boolean instantiateClass(String type_specifier, Declaration decl, IFrame currentFrame) { + + Model clazz = globals.classes.get(type_specifier); + if(clazz == null) return false; + + Map modifications = new HashMap(); + if(decl.modification instanceof ArgumentList) { + ArgumentList args = (ArgumentList)decl.modification; + for(Argument a : args.args) { + modifications.put(a.name, a.modification); + } + } + + for(VariableDeclaration vd : clazz.variables) { + String base = decl.variable.base.name + "."; + Variable var2 = vd.variable.withBase(currentFrame, base); + VariableDeclaration vd2 = new VariableDeclaration(var2, vd.direction, vd.type, vd.modification.withBase(currentFrame, base)); + variables.add(vd2); + } + for(ParameterDeclaration pd : clazz.parameters) { + IExpression modi = modifications.get(pd.variable.base.name); + if(modi != null) { + String base = decl.variable.base.name + "."; + Variable var2 = pd.variable.withBase(currentFrame, base); + var2.subscripts = null; + ParameterDeclaration pd2 = new ParameterDeclaration(var2, modi); + parameters.add(pd2); + modifications.remove(pd.variable.base.name); + } else { + String base = decl.variable.base.name + "."; + Variable var2 = pd.variable.withBase(currentFrame, base); + ParameterDeclaration pd2 = new ParameterDeclaration(var2, pd.modification.withBase(currentFrame, base)); + parameters.add(pd2); + } + } + + if(!modifications.isEmpty()) + throw new IllegalStateException(); + + for(Assignment ass : clazz.assignments) { + Assignment ass2 = ass.withBase(currentFrame, decl.variable.base.name + "."); + assignments.add(ass2); + } + for(Assignment ass : clazz.initials) { + Assignment ass2 = ass.withBase(currentFrame, decl.variable.base.name + "."); + initials.add(ass2); + } + for(Assignment ass : clazz.derivatives) { + Assignment ass2 = ass.withBase(currentFrame, decl.variable.base.name + "."); + derivatives.add(ass2); + } + + return true; + + } + } \ No newline at end of file diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/MultiStatement.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/MultiStatement.java new file mode 100644 index 00000000..fd878fd3 --- /dev/null +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/MultiStatement.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2013 Semantum Oy. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package fi.semantum.sysdyn.solver; + +import java.util.ArrayList; + +public class MultiStatement implements IStatement { + + public ArrayList targets; + public Variable fn; + public ArgumentList args; + + public MultiStatement(ArrayList targets, Variable fn, ArgumentList args) { + this.targets = targets; + this.fn = fn; + this.args = args; + } + + @Override + public String toString() { + return targets + " := " + fn + " " + args; + } + + @Override + public void evaluate(IEnvironment environment) { + ArrayList values = (ArrayList)environment.getSystem().evaluateFunction(environment, fn.base.name, args); + for(int i=0;i copies) { + exp1 = exp1.rewrite(frame, copies); + exp2 = exp2.rewrite(frame, copies); + return this; + } } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Negation.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Negation.java index e810c278..cdf125ba 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Negation.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Negation.java @@ -10,6 +10,8 @@ *******************************************************************************/ package fi.semantum.sysdyn.solver; +import java.util.Map; + public class Negation implements IExpression { public IExpression exp; @@ -32,5 +34,16 @@ public class Negation implements IExpression { public IExpression withBase(IFrame frame, String prefix) { return new Negation(exp.withBase(frame, prefix)); } - + + @Override + public Object getPossibleConstant() { + return null; + } + + @Override + public IExpression rewrite(IFrame frame, Map copies) { + exp = exp.rewrite(frame, copies); + return this; + } + } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/NodeClass.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/NodeClass.java index 9777c7d8..33415ec5 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/NodeClass.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/NodeClass.java @@ -49,7 +49,9 @@ public enum NodeClass { add_op, mul_op, rel_op, - der_initial; + der_initial, + output_expression_list, + extends_clause; private NodeClass() { Parser.nodeNameMap.put(toString(), this); diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/NotEquals.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/NotEquals.java index f6056732..41ca66a5 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/NotEquals.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/NotEquals.java @@ -10,6 +10,8 @@ *******************************************************************************/ package fi.semantum.sysdyn.solver; +import java.util.Map; + public class NotEquals implements IExpression { public IExpression exp1; @@ -34,5 +36,17 @@ public class NotEquals implements IExpression { public IExpression withBase(IFrame frame, String prefix) { return new NotEquals(exp1.withBase(frame, prefix), exp2.withBase(frame, prefix)); } - + + @Override + public Object getPossibleConstant() { + return null; + } + + @Override + public IExpression rewrite(IFrame frame, Map copies) { + exp1 = exp1.rewrite(frame, copies); + exp2 = exp2.rewrite(frame, copies); + return this; + } + } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/NullModification.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/NullModification.java new file mode 100644 index 00000000..287d6180 --- /dev/null +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/NullModification.java @@ -0,0 +1,27 @@ +package fi.semantum.sysdyn.solver; + +import java.util.Map; + +public class NullModification implements IExpression { + + @Override + public Object evaluate(IEnvironment environment) { + return null; + } + + @Override + public IExpression withBase(IFrame frame, String prefix) { + return this; + } + + @Override + public Object getPossibleConstant() { + return this; + } + + @Override + public IExpression rewrite(IFrame frame, Map copies) { + return this; + } + +} diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Or.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Or.java index cdc907e0..e08c3282 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Or.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Or.java @@ -11,22 +11,23 @@ package fi.semantum.sysdyn.solver; import java.util.ArrayList; +import java.util.Map; public class Or implements IExpression { - public ArrayList exps; + public IExpression[] exps; public Or(ArrayList exps) { - this.exps = exps; + this.exps = exps.toArray(new IExpression[exps.size()]); } @Override public String toString() { StringBuilder b = new StringBuilder(); - b.append(exps.get(0)); - for(int i=1;i copies) { + for(int i=0;i copies) { + throw new UnsupportedOperationException(); + } } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Parser.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Parser.java index 195e19d6..cbfac5e7 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Parser.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Parser.java @@ -25,11 +25,11 @@ import fi.semantum.sysdyn.solver.parser.SimpleNode; public class Parser { - public IFrame currentFrame; +// public IFrame currentFrame; private int PRINT = 0; - public Object walk(SimpleNode n, int indent, Model model) { + public Object walk(SimpleNode n, int indent, IFrame model) { Object result = walk_(n, indent, model); if(PRINT > 0) { for(int i=0;i nodeNameMap = new HashMap(); - public Object walk_(SimpleNode n, int indent, Model model) { + public Object walk_(SimpleNode n, int indent, IFrame frame) { + Model model = frame instanceof Model ? (Model)frame : null; + // TODO: most of this should probably be implemented in the parser NodeClass nc = NodeClass.of(n.toString()); if (nc == null) { - if(n.jjtGetNumChildren() == 1) return walk((SimpleNode)n.jjtGetChild(0), indent+2, model); + if(n.jjtGetNumChildren() == 1) return walk((SimpleNode)n.jjtGetChild(0), indent+2, frame); // not sure if this is ever called for(int i=0;i comps = new ArrayList(); for(int i=0;i indices = new ArrayList(); for(int i=0;i indices2 = (ArrayList)walk((SimpleNode)n.jjtGetChild(0), indent+2, model); + ArrayList indices2 = (ArrayList)walk((SimpleNode)n.jjtGetChild(0), indent+2, frame); ArrayList stms = new ArrayList(); for(int i=1;i thens = new ArrayList(); ArrayList elses = new ArrayList(); for(int i=1;i whiles = new ArrayList(); for(int i=1;i vars = (ArrayList)walk((SimpleNode)n.jjtGetChild(0), indent+2, frame); + Variable fn = (Variable)walk((SimpleNode)n.jjtGetChild(1), indent+2, frame); + ArgumentList args = (ArgumentList)walk((SimpleNode)n.jjtGetChild(2), indent+2, frame); + return new MultiStatement(vars, fn, args); + } else { + throw new IllegalStateException(); + } + case output_expression_list: + ArrayList vars = new ArrayList(); + for(int i=0;i elements = new ArrayList(); for(int i=0;i arguments = new ArrayList(); + for(int i=0;i args = new ArrayList(); for(int i=0;i statements = new ArrayList(); for(int i=0;i clauses = new ArrayList(); for(int i=declarationStart;i as = new ArrayList(); - as.add(new Argument("", (IExpression)decl.modification)); - ArgumentList al = new ArgumentList(as); - VariableDeclaration vd = new VariableDeclaration(decl.variable, type_prefix, type_specifier, al); - model.variables.add(vd); - clauses.add(vd); - } else { - if("Real".equals(type_specifier)) { - VariableDeclaration vd = new VariableDeclaration(decl.variable, type_prefix, type_specifier, new ArgumentList(new ArrayList())); - model.variables.add(vd); + + boolean wasClass = model == null ? false : model.instantiateClass(type_specifier, decl, frame); + if(!wasClass) { + + if(decl.modification instanceof ArgumentList) { + VariableDeclaration vd = new VariableDeclaration(decl.variable, type_prefix, type_specifier, (ArgumentList)decl.modification); + if(model != null) + model.addVariable(vd); clauses.add(vd); - } else if("Integer".equals(type_specifier)) { - VariableDeclaration vd = new VariableDeclaration(decl.variable, type_prefix, type_specifier, new ArgumentList(new ArrayList())); - model.variables.add(vd); + } else if (decl.modification instanceof IExpression) { + ArrayList as = new ArrayList(); + as.add(new Argument("", (IExpression)decl.modification)); + ArgumentList al = new ArgumentList(as); + VariableDeclaration vd = new VariableDeclaration(decl.variable, type_prefix, type_specifier, al); + if(model != null) + model.addVariable(vd); clauses.add(vd); - } else if("Boolean".equals(type_specifier)) { + } else { VariableDeclaration vd = new VariableDeclaration(decl.variable, type_prefix, type_specifier, new ArgumentList(new ArrayList())); - model.variables.add(vd); + if(model != null) + model.addVariable(vd); clauses.add(vd); - } else { - Model clazz = model.globals.classes.get(type_specifier); - for(VariableDeclaration vd : clazz.variables) { - String base = decl.variable.base.name + "."; - Variable var2 = vd.variable.withBase(currentFrame, base); - VariableDeclaration vd2 = new VariableDeclaration(var2, vd.direction, vd.type, vd.modification.withBase(currentFrame, base)); - model.variables.add(vd2); - clauses.add(vd2); - } - for(ParameterDeclaration pd : clazz.parameters) { - String base = decl.variable.base.name + "."; - Variable var2 = pd.variable.withBase(currentFrame, base); - ParameterDeclaration pd2 = new ParameterDeclaration(var2, pd.modification.withBase(currentFrame, base)); - model.parameters.add(pd2); - } - for(Assignment ass : clazz.assignments) { - Assignment ass2 = ass.withBase(currentFrame, decl.variable.base.name + "."); - model.assignments.add(ass2); - } - for(Assignment ass : clazz.initials) { - Assignment ass2 = ass.withBase(currentFrame, decl.variable.base.name + "."); - model.initials.add(ass2); - } - for(Assignment ass : clazz.derivatives) { - Assignment ass2 = ass.withBase(currentFrame, decl.variable.base.name + "."); - model.derivatives.add(ass2); - } - } + } + } } return clauses; case component_declaration: - return (Declaration)walk((SimpleNode)n.jjtGetChild(0), indent+2, model); + return (Declaration)walk((SimpleNode)n.jjtGetChild(0), indent+2, frame); case array_subscripts: IExpression[] subs = new IExpression[n.jjtGetNumChildren()]; for(int i=0;i stms2 = new ArrayList(); Function function = new Function(functionName, new StatementList(stms2)); - currentFrame = function; - ArrayList composition = (ArrayList)walk(child, indent+2, model); + ArrayList composition = (ArrayList)walk(child, indent+2, function); for(int i=1;i declarations = (ArrayList)composition.get(i); for(Object os_ : declarations) { - ArrayList os = (ArrayList)os_; - for(Object o : os) { - VariableDeclaration decl = (VariableDeclaration)o; - function.internals.add(decl); + if(os_ instanceof VariableDeclaration) { + VariableDeclaration decl = (VariableDeclaration)os_; + if("input".equals(decl.direction)) function.inputs.add(decl); + else if ("output".equals(decl.direction)) function.outputs.add(decl); + else throw new IllegalStateException(); + } else { + ArrayList os = (ArrayList)os_; + for(Object o : os) { + VariableDeclaration decl = (VariableDeclaration)o; + function.internals.add(decl); + } } } } } ArrayList declarations = (ArrayList)composition.get(0); for(Object os_ : declarations) { - ArrayList os = (ArrayList)os_; - for(Object o : os) { - VariableDeclaration decl = (VariableDeclaration)o; + if(os_ instanceof VariableDeclaration) { + VariableDeclaration decl = (VariableDeclaration)os_; if("input".equals(decl.direction)) function.inputs.add(decl); else if ("output".equals(decl.direction)) function.outputs.add(decl); else throw new IllegalStateException(); + } else { + ArrayList os = (ArrayList)os_; + for(Object o : os) { + VariableDeclaration decl = (VariableDeclaration)o; + if("input".equals(decl.direction)) function.inputs.add(decl); + else if ("output".equals(decl.direction)) function.outputs.add(decl); + else throw new IllegalStateException(); + } } } model.functions.put(functionName, function); - currentFrame = model; return function; } else if("model".equals(n.op)) { - currentFrame = model; - if(n.jjtGetNumChildren() == 1) { - return walk((SimpleNode)n.jjtGetChild(0), indent+2, model); + return walk((SimpleNode)n.jjtGetChild(0), indent+2, frame); } else { System.err.println("undefined children for class_definition model"); } @@ -352,12 +378,18 @@ public class Parser { } else if("class".equals(n.op)) { - Model clazz = new Model(model.globals); SimpleNode specifier = (SimpleNode)n.jjtGetChild(0); + Model clazz = new Model(model.globals, specifier.op, false); model.globals.classes.put(specifier.op, clazz); - currentFrame = clazz; walk(specifier, indent+2, clazz); - currentFrame = model; + + if(clazz.isEnumClass) { + Variable sizeVariable = new Variable(clazz, "size", null); + Variable elementsVariable = new Variable(clazz, "elements", new IExpression[] { new Constant(""+clazz.variables.size()) }); + clazz.parameters.add(new ParameterDeclaration(sizeVariable, sizeVariable.getPossibleConstant())); + clazz.parameters.add(new ParameterDeclaration(elementsVariable, elementsVariable.getPossibleConstant())); + } + return null; } else { @@ -366,11 +398,11 @@ public class Parser { break; case array: if(n.jjtGetNumChildren() == 1) { - ArgumentList al = (ArgumentList)walk((SimpleNode)n.jjtGetChild(0), indent+2, model); + ArgumentList al = (ArgumentList)walk((SimpleNode)n.jjtGetChild(0), indent+2, frame); if("for".equals(al.op)) { ForArray array = new ForArray(); - array.addElement(al.args.get(0).modification); - array.addElement(al.args.get(1)); + array.addElement(al.args[0].modification); + array.addElement(al.args[1]); return array; } else { Array array = new Array(); @@ -382,22 +414,22 @@ public class Parser { if(n.op != null) { return Utils.parsePrimitive(n.op); } else { - return walk((SimpleNode)n.jjtGetChild(0), indent+2, model); + return walk((SimpleNode)n.jjtGetChild(0), indent+2, frame); } case component_reference: if(n.jjtGetNumChildren() == 1) { - return new Variable(currentFrame, n.op, (IExpression[])walk((SimpleNode)n.jjtGetChild(0), indent+2, model)); + return Variable.make(frame, n.op, (IExpression[])walk((SimpleNode)n.jjtGetChild(0), indent+2, frame)); } else { if ("time".equals(n.op)) { return new TimeVariable(); } - return new Variable(currentFrame, n.op, null); + return Variable.make(frame, n.op, null); } case relation: if(n.jjtGetNumChildren() == 3) { - IExpression exp1 = (IExpression)walk((SimpleNode)n.jjtGetChild(0), indent+2, model); - String op = (String)walk((SimpleNode)n.jjtGetChild(1), indent+2, model); - IExpression exp2 = (IExpression)walk((SimpleNode)n.jjtGetChild(2), indent+2, model); + IExpression exp1 = (IExpression)walk((SimpleNode)n.jjtGetChild(0), indent+2, frame); + String op = (String)walk((SimpleNode)n.jjtGetChild(1), indent+2, frame); + IExpression exp2 = (IExpression)walk((SimpleNode)n.jjtGetChild(2), indent+2, frame); String trimmed = op != null ? op.trim() : null; if("<".equals(trimmed)) { return new LessThan(exp1, exp2); @@ -414,13 +446,13 @@ public class Parser { } else return null; } else { - return walk((SimpleNode)n.jjtGetChild(0), indent+2, model); + return walk((SimpleNode)n.jjtGetChild(0), indent+2, frame); } case simple_expression: - if(n.jjtGetNumChildren() == 1) return walk((SimpleNode)n.jjtGetChild(0), indent+2, model); + if(n.jjtGetNumChildren() == 1) return walk((SimpleNode)n.jjtGetChild(0), indent+2, frame); else if(n.jjtGetNumChildren() == 2) { - IExpression start = (IExpression)walk((SimpleNode)n.jjtGetChild(0), indent+2, model); - IExpression end = (IExpression)walk((SimpleNode)n.jjtGetChild(1), indent+2, model); + IExpression start = (IExpression)walk((SimpleNode)n.jjtGetChild(0), indent+2, frame); + IExpression end = (IExpression)walk((SimpleNode)n.jjtGetChild(1), indent+2, frame); return new ArraySliceExpression(start, end); } else { throw new UnsupportedOperationException(); @@ -429,21 +461,21 @@ public class Parser { if(n.jjtGetNumChildren() > 1) { ArrayList logs = new ArrayList(); for(int i=0;i 1) { ArrayList terms = new ArrayList(); for(int i=0;i 1) { - IExpression term = (IExpression)walk((SimpleNode)n.jjtGetChild(0), indent+2, model); + IExpression term = (IExpression)walk((SimpleNode)n.jjtGetChild(0), indent+2, frame); for(int i=1;i 0) { + while(condition > 0 && loops++ < 50) { - koss = 0; +// System.err.println("== LOOP " + loops + " =="); + + condition = 0; for(ParameterDeclaration pd : model.parameters) { try { @@ -98,7 +101,7 @@ public class Solver { pd.assigned = true; } } catch (Exception e) { - koss++; + condition++; if(PRINT_EXCEPTIONS) { e.printStackTrace(); System.err.println("failed to assign " + pd.variable.toString()); @@ -114,9 +117,19 @@ public class Solver { try { if(!vd.assigned) { for(Argument arg : vd.modification.args) { - if("start".equals(arg.name)) { + if(arg.name.endsWith("start")) { Object value = arg.modification.evaluate(env); - vd.variable.assign(env, null, value); + if(vd.variable.base.dimension() == 1) { + vd.variable.assign(env, null, value); + } else { + if(value instanceof Double) { + Array array = new Array(); + for(int i=0;i copies) { + exp1 = exp1.rewrite(frame, copies); + exp2 = exp2.rewrite(frame, copies); + return this; + } + } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/TimeVariable.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/TimeVariable.java index 8a4178ee..d2d3e4c6 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/TimeVariable.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/TimeVariable.java @@ -10,6 +10,8 @@ *******************************************************************************/ package fi.semantum.sysdyn.solver; +import java.util.Map; + public class TimeVariable implements IExpression { @Override @@ -27,6 +29,15 @@ public class TimeVariable implements IExpression { public IExpression withBase(IFrame frame, String prefix) { return this; } + + @Override + public Object getPossibleConstant() { + return null; + } + @Override + public IExpression rewrite(IFrame frame, Map copies) { + return this; + } } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Variable.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Variable.java index 632fc537..183d0cc3 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Variable.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/Variable.java @@ -11,7 +11,8 @@ *******************************************************************************/ package fi.semantum.sysdyn.solver; -import org.omg.PortableInterceptor.SUCCESSFUL; +import java.util.Map; + public class Variable implements IExpression { @@ -24,6 +25,14 @@ public class Variable implements IExpression { this.subscripts = subscripts; } + public static Object make(IFrame frame, String name, IExpression[] subscripts) { +// Array enumElements = enumerationElements(frame, name); +// if(enumElements != null) return enumElements; +// Constant enumSize = enumerationSize(frame, name); +// if(enumSize != null) return enumSize; + return new Variable(frame, name, subscripts); + } + public Variable(VariableBase base) { this.base = base; } @@ -32,28 +41,6 @@ public class Variable implements IExpression { this.base = base; this.subscripts = subscripts; } - - private int makeSubscriptIndex(IEnvironment env) { - if(base.dimensions == null) return 0; - int result = 0; - for(int i=0;i 1) { - Array array = new Array(); - intoArray(environment, base.index, 0, array); - return array; - } - - Object result = environment.getNamedValue(base.name); - if(result == null) result = environment.getValue(index(environment, subscripts)); - if(result == null) throw new UnassignedVariableException("No value for " + base.name); - - return result; - } - } - - private boolean hasScalarSubscript(IExpression[] subscripts) { - if(subscripts == null) return false; - else return true; - } +// static Array enumerationElements(IFrame frame, String name) { +// if(!name.endsWith(".elements")) return null; +// String prefix = name.replace(".elements", ""); +// Model m = frame.getClass(prefix + "_class"); +// if(m == null) return null; +// Array result = new Array(); +// for(VariableDeclaration vd : m.variables) { +// Constant c = (Constant)vd.modification.args.get(0).modification; +// result.addElement(c.value); +// } +// return result; +// } +// +// static Constant enumerationSize(IFrame frame, String name) { +// if(!name.endsWith(".size")) return null; +// String prefix = name.replace(".size", ""); +// Model m = frame.getClass(prefix + "_class"); +// if(m == null) return null; +// return new Constant("" + m.variables.size()); +// } + public Variable withBase(IFrame frame, String prefix) { + if(subscripts != null) { IExpression[] subscripts2 = new IExpression[subscripts.length]; for(int i=0;i copies) { + VariableBase copy = copies.get(base.name); + if(copy == null) { + if(subscripts != null) { + for(int i=0;i dimensions[i]) dimensions[i] = index; + public boolean tellSubscripts(IExpression[] e, IExpression modification) { + + if(dimensions != UNINIT) return true; + + if(e != null) { + + if(dimensions == UNINIT) + dimensions = new int[e.length]; + + if(e.length == 0) + throw new IllegalStateException(); + + for(int i=0;i dimensions[i]) dimensions[i] = index; + } } + + } else { + + dimensions = null; + } + + return dimensions != UNINIT; + } public int dimension() { if(dimensions == null) return 1; @@ -59,5 +92,126 @@ public class VariableBase { VariableBase withBase(String prefix) { return new VariableBase(prefix+name, index, dimensions); } + + private int makeSubscriptIndex(IEnvironment env, IExpression[] subscripts) { + if(dimensions == null) return 0; + int result = 0; + for(int i=0;i 1) { + if(subscripts != null) { + + Slice[] sub = SolverUtils.parseSubscripts(environment, subscripts); + if(SolverUtils.isSlice(sub)) { + Array arr = new Array(); + intoArray(environment, index, 0, arr); + return arr.slice(sub); + } else { + return environment.getValue(index(environment, subscripts)); + } + + } else { + Array array = new Array(); + intoArray(environment, index, 0, array); + return array; + } + } + + Object result = environment.getNamedValue(name); + if(result == null) result = environment.getValue(index(environment, subscripts)); + if(result == null) throw new UnassignedVariableException("No value for " + name); + + if(SolverUtils.isArray(dimensions) && subscripts == null) { + return new Array().addElement(result); + } else { + return result; + } + + } + } + + public IExpression getPossibleConstant() { + return null; + } } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/VariableDeclaration.java b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/VariableDeclaration.java index 89d0f456..08c8a49d 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/VariableDeclaration.java +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/VariableDeclaration.java @@ -10,6 +10,8 @@ *******************************************************************************/ package fi.semantum.sysdyn.solver; +import java.util.Map; + public class VariableDeclaration implements IExpression { @@ -40,5 +42,15 @@ public class VariableDeclaration implements IExpression { public IExpression withBase(IFrame frame, String prefix) { throw new UnsupportedOperationException(); } + + @Override + public Object getPossibleConstant() { + return null; + } + + @Override + public IExpression rewrite(IFrame frame, Map copies) { + throw new UnsupportedOperationException(); + } } diff --git a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelicaParser.jjt b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelicaParser.jjt index d95e0cdd..422e38fd 100644 --- a/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelicaParser.jjt +++ b/fi.semantum.sysdyn.solver/src/fi/semantum/sysdyn/solver/parser/ModelicaParser.jjt @@ -71,10 +71,10 @@ TOKEN: | "*" | "/" | ".*" | "./" | "^" | ".^" | "=" | ":=" -| +| | { matchedToken.image = matchedToken.image.substring(1,matchedToken.image.length()-1); } -| +| | "." ()? (["e","E"] )? | "." (["e","E"] )? @@ -137,9 +137,9 @@ void class_specifier() : { Token t; // end IDENT LOOKAHEAD(2) t= { jjtThis.op = t.image; } string_comment() composition() "end" | LOOKAHEAD(2) "=" base_prefix() name() ( array_subscripts() )? ( class_modification() )? comment() + | LOOKAHEAD(3) "=" "der" "(" name() "," ( "," )* ")" comment() | LOOKAHEAD(3) "=" "enumeration" "(" ( ( enum_list() )? | ":" ) ")" comment() - |LOOKAHEAD(3) "=" "der" "(" name() "," ( "," )* ")" comment() - | "extends" ( class_modification() )? string_comment() composition() "end" + //| "extends" ( class_modification() )? string_comment() composition() "end" } void base_prefix() : { @@ -208,8 +208,8 @@ Node element() : { // ( ( class_definition | component_clause) | // replaceable ( class_definition | component_clause) // [constraining_clause comment]) - import_clause() | - extends_clause() | + import_clause() { return jjtThis; } | + extends_clause() { return jjtThis; } | ( "redeclare" )? ( "final" )? ( "inner" { jjtThis.op = "inner"; } )? ( "outer" { jjtThis.op = "outer"; } )? @@ -656,7 +656,12 @@ void mul_op() : { void factor() : { } { - primary() ( "^" | ".^" primary() )? + primary() ( factor_op() primary() )? +} + +void factor_op() : { +} { + "^" { jjtThis.op = "^";} | ".^" { jjtThis.op = ".^";} } void der_initial() : {