diff --git a/AlgebraicDataflowArchitectureModel/models/Kinetics.model b/AlgebraicDataflowArchitectureModel/models/Kinetics.model new file mode 100644 index 0000000..4b446cb --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/models/Kinetics.model @@ -0,0 +1,20 @@ +channel CIO { + out force(f, push(x)) == x + out time(t, push(x)) == t + 0.01 +} + +channel C1 { + in force(f, update1(y, m)) == y + in mass(m, update1(y, m)) == m + out acceleration(a, update1(y, m)) == y / m +} + +channel C2 { + in acceleration(a, update2(z)) == z + out velocity(v, update2(z)) == v + 0.01 * z +} + +channel C3 { + in velocity(v, update3(v)) == u + out position(p, update3(v)) == p + 0.01 * v +} \ No newline at end of file diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Constant.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Constant.java index 0c283a5..690b9ec 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Constant.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Constant.java @@ -8,6 +8,15 @@ super(new Symbol(value, 0), new ArrayList()); } + public Constant(String value, Type type) { + super(new Symbol(value, 0), new ArrayList()); + symbol.setSignature(new Type[] {type}); + } + + public Constant(Symbol symbol) { + super(symbol); + } + @Override public boolean equals(Object another) { if (!(another instanceof Constant)) return false; @@ -16,7 +25,7 @@ @Override public Object clone() { - return new Constant(symbol.getName()); + return new Constant(symbol); } public String toString() { diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Expression.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Expression.java index 6e0c9e2..9ba946c 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Expression.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Expression.java @@ -3,10 +3,14 @@ import java.util.HashMap; public abstract class Expression implements Cloneable { - public abstract HashMap getVariables(); public abstract Expression getSubTerm(Position pos); public abstract Expression unify(Expression another); public abstract Expression getInverseMap(Expression outputValue, Position targetPos); public abstract boolean contains(Expression exp); public abstract Object clone(); + public abstract HashMap getSubTerms(Class clazz); + + public HashMap getVariables() { + return getSubTerms(Variable.class); + } } diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Field.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Field.java new file mode 100644 index 0000000..a95a1c4 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Field.java @@ -0,0 +1,41 @@ +package models.algebra; + +import java.util.ArrayList; + +/** + * A field in the implementation (regarded as a constant in the algebraic system) + * @author Nitta + * + */ +public class Field extends Constant { + + public Field(String name) { + super(name); + } + + public Field(String name, Type type) { + super(name, type); + } + + public Field(Symbol symbol) { + super(symbol); + } + + public Type getType() { + if (symbol.getSignature().length >= 1) { + return symbol.getSignature()[0]; + } + return null; + } + + @Override + public boolean equals(Object another) { + if (!(another instanceof Field)) return false; + return symbol.equals(((Field) another).symbol); + } + + @Override + public Object clone() { + return new Field(symbol); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Parameter.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Parameter.java new file mode 100644 index 0000000..739ab80 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Parameter.java @@ -0,0 +1,39 @@ +package models.algebra; + +/** + * A parameter in the implementation (regarded as a constant in the algebraic system) + * @author Nitta + * + */ +public class Parameter extends Constant { + + public Parameter(String name) { + super(name); + } + + public Parameter(String name, Type type) { + super(name, type); + } + + public Parameter(Symbol symbol) { + super(symbol); + } + + public Type getType() { + if (symbol.getSignature().length >= 1) { + return symbol.getSignature()[0]; + } + return null; + } + + @Override + public boolean equals(Object another) { + if (!(another instanceof Parameter)) return false; + return symbol.equals(((Parameter) another).symbol); + } + + @Override + public Object clone() { + return new Parameter(symbol); + } +} diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Symbol.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Symbol.java index 8204dea..0c9c9b8 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Symbol.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Symbol.java @@ -5,7 +5,7 @@ private int arity = 0; private Type operatorType = Type.PREFIX; private Symbol[] inverses = null; - private Type[] signature = null; + private models.algebra.Type[] signature = null; public Symbol(String name) { this.name = name; @@ -51,11 +51,11 @@ this.inverses = inverses; } - public Type[] getSignature() { + public models.algebra.Type[] getSignature() { return signature; } - public void setSignature(Type[] signature) { + public void setSignature(models.algebra.Type[] signature) { this.signature = signature; } diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java index 023f5f8..6a02785 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Term.java @@ -42,17 +42,20 @@ return children.get(n); } - public HashMap getVariables() { - HashMap variables = new HashMap<>(); + public HashMap getSubTerms(Class clazz) { + HashMap subTerms = new HashMap<>(); + if (clazz == this.getClass()) { + subTerms.put(new Position(), (T) this); + } for (int i = 0; i < children.size(); i++) { - HashMap vars = children.get(i).getVariables(); - for (Entry var: vars.entrySet()) { - Position pos = var.getKey(); + HashMap terms = children.get(i).getSubTerms(clazz); + for (Entry term: terms.entrySet()) { + Position pos = term.getKey(); pos.addHeadOrder(i); - variables.put(pos, var.getValue()); + subTerms.put(pos, term.getValue()); } } - return variables; + return subTerms; } public Expression getSubTerm(Position pos) { diff --git a/AlgebraicDataflowArchitectureModel/src/models/algebra/Variable.java b/AlgebraicDataflowArchitectureModel/src/models/algebra/Variable.java index 935503b..99ae839 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/algebra/Variable.java +++ b/AlgebraicDataflowArchitectureModel/src/models/algebra/Variable.java @@ -30,10 +30,12 @@ } @Override - public HashMap getVariables() { - HashMap variables = new HashMap<>(); - variables.put(new Position(), this); - return variables; + public HashMap getSubTerms(Class clazz) { + HashMap subTerms = new HashMap<>(); + if (clazz == this.getClass()) { + subTerms.put(new Position(), (T) this); + } + return subTerms; } @Override diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/StateTransition.java b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/StateTransition.java index 06ca47b..2bfb09b 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/StateTransition.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataConstraintModel/StateTransition.java @@ -41,7 +41,7 @@ this.messageExpression = messageExpression; } - public Expression deriveMessageConstraintFor(Expression curState, Expression nextState) throws InvalidMessage, ResolvingMultipleDefinitionIsFutureWork { + public Expression deriveMessageConstraintFor(Expression curStateValue, Expression nextStateValue) throws InvalidMessage, ResolvingMultipleDefinitionIsFutureWork { HashMap> bindings = new HashMap<>(); Expression curStateTerm = getCurStateExpression(); @@ -49,7 +49,7 @@ for (Entry curStateVarEnt: curStateVars.entrySet()) { Variable var = curStateVarEnt.getValue(); Position varPos = curStateVarEnt.getKey(); - Expression valueCalc = curStateTerm.getInverseMap(curState, varPos); + Expression valueCalc = curStateTerm.getInverseMap(curStateValue, varPos); if (valueCalc != null) { ArrayList values = bindings.get(var); if (values == null) { @@ -65,7 +65,11 @@ HashMap vars2 = nextStateTerm.getVariables(); for (Variable var2: vars2.values()) { if (var.equals(var2) && bindings.get(var).size() == 1) { - nextStateTerm = ((Term) nextStateTerm).substitute(var, bindings.get(var).get(0)); + if (nextStateTerm instanceof Term) { + nextStateTerm = ((Term) nextStateTerm).substitute(var, bindings.get(var).get(0)); + } else if (nextStateTerm instanceof Variable && nextStateTerm.equals(var)) { + nextStateTerm = bindings.get(var).get(0); + } } } } @@ -74,7 +78,7 @@ for (Entry nextStateVarEnt: nextStateVars.entrySet()) { Variable var = nextStateVarEnt.getValue(); Position varPos = nextStateVarEnt.getKey(); - Expression valueCalc = nextStateTerm.getInverseMap(nextState, varPos); + Expression valueCalc = nextStateTerm.getInverseMap(nextStateValue, varPos); if (valueCalc != null) { ArrayList values = bindings.get(var); if (values == null) { @@ -97,7 +101,7 @@ return messageTerm; } - public Expression deriveNextStateExpressionFor(Expression curState, Term concreteMessage) + public Expression deriveNextStateExpressionFor(Expression curStateValue, Term concreteMessage) throws ResolvingMultipleDefinitionIsFutureWork, ValueUndefined { HashMap bindings = new HashMap<>(); @@ -106,7 +110,7 @@ for (Entry curStateVarEnt: curStateVars.entrySet()) { Variable var = curStateVarEnt.getValue(); Position varPos = curStateVarEnt.getKey(); - Expression valueCalc = curStateTerm.getInverseMap(curState, varPos); + Expression valueCalc = curStateTerm.getInverseMap(curStateValue, varPos); if (valueCalc != null) { if (bindings.get(var) != null) throw new ResolvingMultipleDefinitionIsFutureWork(); bindings.put(var, valueCalc); diff --git a/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataflowChannelGenerator.java b/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataflowChannelGenerator.java index 46f6ade..42fc9ac 100644 --- a/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataflowChannelGenerator.java +++ b/AlgebraicDataflowArchitectureModel/src/models/dataFlowModel/DataflowChannelGenerator.java @@ -6,11 +6,11 @@ import models.algebra.Expression; import models.algebra.InvalidMessage; +import models.algebra.Parameter; import models.algebra.ParameterizedIdentifierIsFutureWork; import models.algebra.Term; import models.algebra.UnificationFailed; import models.algebra.ValueUndefined; -import models.algebra.Variable; import models.dataConstraintModel.*; public class DataflowChannelGenerator extends ChannelGenerator { @@ -75,15 +75,15 @@ public Expression deriveUpdateExpressionOf(ChannelMember targetMember) throws ParameterizedIdentifierIsFutureWork, ResolvingMultipleDefinitionIsFutureWork, InvalidMessage, UnificationFailed, ValueUndefined { IResourceStateAccessor defaultStateAccessor = new IResourceStateAccessor() { - HashMap curStateParams = new HashMap<>(); - HashMap nextStateParams = new HashMap<>(); + HashMap curStateParams = new HashMap<>(); + HashMap nextStateParams = new HashMap<>(); @Override public Expression getCurrentStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { String resource = target.getResourceName(); - Variable curStateParam = curStateParams.get(resource); + Parameter curStateParam = curStateParams.get(resource); if (curStateParam == null) { - curStateParam = new Variable("cur" + resource); + curStateParam = new Parameter("cur" + resource); curStateParams.put(resource, curStateParam); } return curStateParam; @@ -92,9 +92,9 @@ @Override public Expression getNextStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { String resource = target.getResourceName(); - Variable nextStateParam = nextStateParams.get(resource); + Parameter nextStateParam = nextStateParams.get(resource); if (nextStateParam == null) { - nextStateParam = new Variable("next" + resource); + nextStateParam = new Parameter("next" + resource); nextStateParams.put(resource, nextStateParam); } return nextStateParam; diff --git a/AlgebraicDataflowArchitectureModel/src/tests/ParseTest.java b/AlgebraicDataflowArchitectureModel/src/tests/ParseTest.java index 2af9ed1..598c922 100644 --- a/AlgebraicDataflowArchitectureModel/src/tests/ParseTest.java +++ b/AlgebraicDataflowArchitectureModel/src/tests/ParseTest.java @@ -43,8 +43,9 @@ System.out.println(model); for (ChannelGenerator c: model.getChannelGenerators()) { - ChannelMember out = ((DataflowChannelGenerator) c).getOutputChannelMembers().iterator().next(); - System.out.println("next" + out.getIdentifierTemplate().getResourceName() + " = " + ((DataflowChannelGenerator) c).deriveUpdateExpressionOf(out)); + for (ChannelMember out: ((DataflowChannelGenerator) c).getOutputChannelMembers()) { + System.out.println("next" + out.getIdentifierTemplate().getResourceName() + " = " + ((DataflowChannelGenerator) c).deriveUpdateExpressionOf(out)); + } } System.out.println(); diff --git a/AlgebraicDataflowArchitectureModel/src/tests/UpdateCodeGenerationTest.java b/AlgebraicDataflowArchitectureModel/src/tests/UpdateCodeGenerationTest.java index a10c032..0955539 100644 --- a/AlgebraicDataflowArchitectureModel/src/tests/UpdateCodeGenerationTest.java +++ b/AlgebraicDataflowArchitectureModel/src/tests/UpdateCodeGenerationTest.java @@ -6,7 +6,9 @@ import models.algebra.Constant; import models.algebra.Expression; +import models.algebra.Field; import models.algebra.InvalidMessage; +import models.algebra.Parameter; import models.algebra.ParameterizedIdentifierIsFutureWork; import models.algebra.Symbol; import models.algebra.Term; @@ -36,15 +38,15 @@ IdentifierTemplate total = new IdentifierTemplate("total", DataConstraintModel.typeInt, 0); // an identifier template to specify the total payment resource // fields - final Variable fPayment = new Variable("fPayment", DataConstraintModel.typeInt); - final Variable fLoyalty = new Variable("fLoyalty", DataConstraintModel.typeInt); - final Variable fHistory = new Variable("fHistory", DataConstraintModel.typeList); - final Variable fTotal = new Variable("fTotal", DataConstraintModel.typeInt); - // arguments - final Variable aPayment = new Variable("payment", DataConstraintModel.typeInt); - final Variable aLoyalty = new Variable("loyalty", DataConstraintModel.typeInt); - final Variable aHistory = new Variable("history", DataConstraintModel.typeList); - final Variable aTotal = new Variable("total", DataConstraintModel.typeInt); + final Field fPayment = new Field("payment", DataConstraintModel.typeInt); + final Field fLoyalty = new Field("loyalty", DataConstraintModel.typeInt); + final Field fHistory = new Field("history", DataConstraintModel.typeList); + final Field fTotal = new Field("total", DataConstraintModel.typeInt); + // parameters + final Parameter pPayment = new Parameter("payment", DataConstraintModel.typeInt); + final Parameter pLoyalty = new Parameter("loyalty", DataConstraintModel.typeInt); + final Parameter pHistory = new Parameter("history", DataConstraintModel.typeList); + final Parameter pTotal = new Parameter("total", DataConstraintModel.typeInt); IResourceStateAccessor pushAccessor = new IResourceStateAccessor() { @Override public Expression getCurrentStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { @@ -58,10 +60,10 @@ } @Override public Expression getNextStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) { - if (target.equals(payment)) return aPayment; - if (target.equals(loyalty)) return aLoyalty; - if (target.equals(history)) return aHistory; - if (target.equals(total)) return aTotal; + if (target.equals(payment)) return pPayment; + if (target.equals(loyalty)) return pLoyalty; + if (target.equals(history)) return pHistory; + if (target.equals(total)) return pTotal; return null; } }; @@ -151,14 +153,14 @@ System.out.println("-- PUSH --"); Expression loyaltyPushUpdate = c1.deriveUpdateExpressionOf(c1_loyalty, pushAccessor); - Variable arg = null; - for (Variable v: loyaltyPushUpdate.getVariables().values()) { - if (v.equals(aPayment) || v.equals(aLoyalty) || v.equals(aHistory) || v.equals(aTotal)) { - arg = v; + Parameter param = null; + for (Parameter p: loyaltyPushUpdate.getSubTerms(Parameter.class).values()) { + if (p.equals(pPayment) || p.equals(pLoyalty) || p.equals(pHistory) || p.equals(pTotal)) { + param = p; break; } } - System.out.println("void update(" + arg.getType().getImplementastionTypeName() + " " + arg + ") {"); + System.out.println("void update(" + param.getType().getImplementastionTypeName() + " " + param + ") {"); System.out.println("\t" + fLoyalty + " = " + loyaltyPushUpdate + ";"); System.out.println("}"); @@ -213,14 +215,14 @@ System.out.println("-- PUSH --"); Expression historyPushUpdate = c2.deriveUpdateExpressionOf(c2_history, pushAccessor); - Variable arg = null; - for (Variable v: historyPushUpdate.getVariables().values()) { - if (v.equals(aPayment) || v.equals(aLoyalty) || v.equals(aHistory) || v.equals(aTotal)) { - arg = v; + Parameter param = null; + for (Parameter p: historyPushUpdate.getSubTerms(Parameter.class).values()) { + if (p.equals(pPayment) || p.equals(pLoyalty) || p.equals(pHistory) || p.equals(pTotal)) { + param = p; break; } } - System.out.println("void update(" + arg.getType().getImplementastionTypeName() + " " + arg + ") {"); + System.out.println("void update(" + param.getType().getImplementastionTypeName() + " " + param + ") {"); System.out.println("\t" + fHistory + " = " + historyPushUpdate + ";"); System.out.println("}"); @@ -275,14 +277,14 @@ System.out.println("-- PUSH --"); Expression totalPushUpdate = c3.deriveUpdateExpressionOf(c3_total, pushAccessor); - Variable arg = null; - for (Variable v: totalPushUpdate.getVariables().values()) { - if (v.equals(aPayment) || v.equals(aLoyalty) || v.equals(aHistory) || v.equals(aTotal)) { - arg = v; + Parameter param = null; + for (Parameter p: totalPushUpdate.getSubTerms(Parameter.class).values()) { + if (p.equals(pPayment) || p.equals(pLoyalty) || p.equals(pHistory) || p.equals(pTotal)) { + param = p; break; } } - System.out.println("void update(" + arg.getType().getImplementastionTypeName() + " " + arg + ") {"); + System.out.println("void update(" + param.getType().getImplementastionTypeName() + " " + param + ") {"); System.out.println("\t" + fTotal + " = " + totalPushUpdate + ";"); System.out.println("}");