package tests;
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;
import models.algebra.UnificationFailed;
import models.algebra.ValueUndefined;
import models.algebra.Variable;
import models.dataConstraintModel.*;
import models.dataFlowModel.DataTransferModel;
import models.dataFlowModel.DataTransferChannel;
import models.dataFlowModel.DataTransferChannel.IResourceStateAccessor;
import models.dataFlowModel.ResolvingMultipleDefinitionIsFutureWork;
public class UpdateCodeGenerationTest {
public static void main(String[] args) {
// Pre-defined symbols
Symbol floor = new Symbol("floor", 1, Symbol.Type.PREFIX, "(int)Math.floor", Symbol.Type.PREFIX);
Symbol sum = new Symbol("sum", 1, Symbol.Type.PREFIX, "stream().mapToInt(x->x).sum", Symbol.Type.METHOD);
// resources
ResourcePath payment = new ResourcePath("payment"); // a resource to specify the payment resource
ResourcePath points = new ResourcePath("points"); // a resource to specify the loyalty resource
ResourcePath history = new ResourcePath("history"); // a resource to specify the payment history resource
ResourcePath total = new ResourcePath("total"); // a resource to specify the total payment resource
payment.setResourceStateType(DataConstraintModel.typeInt);
points.setResourceStateType(DataConstraintModel.typeInt);
history.setResourceStateType(DataConstraintModel.typeInt);
total.setResourceStateType(DataConstraintModel.typeInt);
// fields in the Java program
final Field fPayment = new Field("payment", DataConstraintModel.typeInt);
final Field fPoints = new Field("points", DataConstraintModel.typeInt);
final Field fHistory = new Field("history", DataConstraintModel.typeList);
final Field fTotal = new Field("total", DataConstraintModel.typeInt);
// parameters in the Java program
final Parameter pPayment = new Parameter("payment", DataConstraintModel.typeInt);
final Parameter pPoints = new Parameter("points", 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(ChannelMember target, ChannelMember from) {
ResourcePath targetRes = target.getResource();
ResourcePath fromRes = from.getResource();
if (targetRes.equals(fromRes)) {
if (targetRes.equals(payment)) return fPayment;
if (targetRes.equals(points)) return fPoints;
if (targetRes.equals(history)) return fHistory;
if (targetRes.equals(total)) return fTotal;
}
return null;
}
@Override
public Expression getNextStateAccessorFor(ChannelMember target, ChannelMember from) {
ResourcePath targetRes = target.getResource();
if (targetRes.equals(payment)) return pPayment;
if (targetRes.equals(points)) return pPoints;
if (targetRes.equals(history)) return pHistory;
if (targetRes.equals(total)) return pTotal;
return null;
}
@Override
public Expression getDirectStateAccessorFor(ResourcePath targetRes, ResourcePath fromRes) {
return null;
}
};
// methods in the Java program
final Symbol paymentGetter = new Symbol("getPayment", 1, Symbol.Type.METHOD);
final Symbol pointsGetter = new Symbol("getPoints", 1, Symbol.Type.METHOD);
final Symbol historyGetter = new Symbol("getHistory", 1, Symbol.Type.METHOD);
final Symbol totalGetter = new Symbol("getTotal", 1, Symbol.Type.METHOD);
IResourceStateAccessor pullAccessor = new IResourceStateAccessor() {
@Override
public Expression getCurrentStateAccessorFor(ChannelMember target, ChannelMember from) {
ResourcePath targetRes = target.getResource();
ResourcePath fromRes = from.getResource();
if (targetRes.equals(fromRes)) {
if (targetRes.equals(payment)) return fPayment;
if (targetRes.equals(points)) return fPoints;
if (targetRes.equals(history)) return fHistory;
if (targetRes.equals(total)) return fTotal;
}
return null;
}
@Override
public Expression getNextStateAccessorFor(ChannelMember target, ChannelMember from) {
ResourcePath targetRes = target.getResource();
if (targetRes.equals(payment)) {
Term getter = new Term(paymentGetter);
getter.addChild(fPayment);
return getter;
}
if (targetRes.equals(points)) {
Term getter = new Term(pointsGetter);
getter.addChild(fPoints);
return getter;
}
if (targetRes.equals(history)) {
Term getter = new Term(historyGetter);
getter.addChild(fHistory);
return getter;
}
if (targetRes.equals(total)) {
Term getter = new Term(totalGetter);
getter.addChild(fTotal);
return getter;
}
return null;
}
@Override
public Expression getDirectStateAccessorFor(ResourcePath targetRes, ResourcePath fromRes) {
return null;
}
};
// === c1 ===
//
// payment(p1, update1(y)) = y
// points(l, update1(y)) = floor(y * 0.05)
//
DataTransferChannel c1 = new DataTransferChannel("c1");
ChannelMember c1_payment = new ChannelMember(payment);
ChannelMember c1_loyalty = new ChannelMember(points);
c1.addChannelMemberAsInput(c1_payment);
c1.addChannelMemberAsOutput(c1_loyalty);
Variable p1 = new Variable("p1");
Variable y = new Variable("y");
Variable l = new Variable("l");
Constant c_0_05 = new Constant("0.05");
Symbol update1 = new Symbol("update1", 1);
Term c1_message = new Term(update1); // update1(y)
c1_message.addChild(y);
Term rawPoints = new Term(DataConstraintModel.mul); // y*0.05
rawPoints.addChild(y);
rawPoints.addChild(c_0_05);
Term nextPoints = new Term(floor); // floor(y*0.05)
nextPoints.addChild(rawPoints);
StateTransition c1_payment_transition = new StateTransition();
c1_payment_transition.setCurStateExpression(p1);
c1_payment_transition.setMessageExpression(c1_message);
c1_payment_transition.setNextStateExpression(y);
c1_payment.setStateTransition(c1_payment_transition);
StateTransition c1_points_transition = new StateTransition();
c1_points_transition.setCurStateExpression(l);
c1_points_transition.setMessageExpression(c1_message);
c1_points_transition.setNextStateExpression(nextPoints);
c1_loyalty.setStateTransition(c1_points_transition);
System.out.println(c1);
try {
String[] sideEffects = new String[] {""};
System.out.println("-----");
System.out.println(c1.deriveUpdateExpressionOf(c1_loyalty).toImplementation(sideEffects));
System.out.println("-- PUSH --");
Expression loyaltyPushUpdate = c1.deriveUpdateExpressionOf(c1_loyalty, pushAccessor).getKey();
Parameter param = null;
for (Parameter p: loyaltyPushUpdate.getSubTerms(Parameter.class).values()) {
if (p.equals(pPayment) || p.equals(pPoints) || p.equals(pHistory) || p.equals(pTotal)) {
param = p;
break;
}
}
System.out.println("void update(" + param.getType().getImplementationTypeName() + " " + param.toImplementation(sideEffects) + ") {");
System.out.println("\t" + fPoints + " = " + loyaltyPushUpdate.toImplementation(sideEffects) + ";");
System.out.println("}");
System.out.println("-- PULL --");
System.out.println(points.getResourceStateType().getImplementationTypeName() + " " + pointsGetter.toImplementation() + "() {");
System.out.println("\t return " + c1.deriveUpdateExpressionOf(c1_loyalty, pullAccessor).getKey().toImplementation(sideEffects) + ";");
System.out.println("}");
} catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork | InvalidMessage
| UnificationFailed | ValueUndefined e) {
e.printStackTrace();
}
System.out.println("==========");
// === c2 ===
//
// payment(p1, update2(z)) = z
// history(h, update2(z)) = cons(z, h)
//
DataTransferChannel c2 = new DataTransferChannel("c2");
ChannelMember c2_payment = new ChannelMember(payment);
ChannelMember c2_history = new ChannelMember(history);
c2.addChannelMemberAsInput(c2_payment);
c2.addChannelMemberAsOutput(c2_history);
Variable z = new Variable("z");
Variable h = new Variable("h");
Symbol update2 = new Symbol("update2", 1);
Term c2_message = new Term(update2); // update2(z)
c2_message.addChild(z);
Term nextHistory = new Term(DataTransferModel.cons); // cons(z, h)
nextHistory.addChild(z);
nextHistory.addChild(h);
StateTransition c2_payment_transition = new StateTransition();
c2_payment_transition.setCurStateExpression(p1);
c2_payment_transition.setMessageExpression(c2_message);
c2_payment_transition.setNextStateExpression(z);
c2_payment.setStateTransition(c2_payment_transition);
StateTransition c2_history_transition = new StateTransition();
c2_history_transition.setCurStateExpression(h);
c2_history_transition.setMessageExpression(c2_message);
c2_history_transition.setNextStateExpression(nextHistory);
c2_history.setStateTransition(c2_history_transition);
System.out.println(c2);
try {
String[] sideEffects = new String[] {""};
System.out.println("-----");
System.out.println(c2.deriveUpdateExpressionOf(c2_history).toImplementation(sideEffects));
System.out.println("-- PUSH --");
Expression historyPushUpdate = c2.deriveUpdateExpressionOf(c2_history, pushAccessor).getKey();
Parameter param = null;
for (Parameter p: historyPushUpdate.getSubTerms(Parameter.class).values()) {
if (p.equals(pPayment) || p.equals(pPoints) || p.equals(pHistory) || p.equals(pTotal)) {
param = p;
break;
}
}
System.out.println("void update(" + param.getType().getImplementationTypeName() + " " + param.toImplementation(sideEffects) + ") {");
System.out.println("\t" + fHistory + " = " + historyPushUpdate.toImplementation(sideEffects) + ";");
System.out.println("}");
System.out.println("-- PULL --");
System.out.println(history.getResourceStateType().getImplementationTypeName() + " " + historyGetter.toImplementation() + "() {");
System.out.println("\t return " + c2.deriveUpdateExpressionOf(c2_history, pullAccessor).getKey().toImplementation(sideEffects) + ";");
System.out.println("}");
} catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork | InvalidMessage
| UnificationFailed | ValueUndefined e) {
e.printStackTrace();
}
System.out.println("==========");
// === c3 ===
//
// history(h, update3(u)) = u
// total(t, update3(u)) = sum(u)
//
DataTransferChannel c3 = new DataTransferChannel("c3");
ChannelMember c3_history = new ChannelMember(history);
ChannelMember c3_total = new ChannelMember(total);
c3.addChannelMemberAsInput(c3_history);
c3.addChannelMemberAsOutput(c3_total);
Variable u = new Variable("u");
Variable t = new Variable("t");
Symbol update3 = new Symbol("update3", 1);
Term c3_message = new Term(update3); // update3(u)
c3_message.addChild(u);
Expression nextHistory2 = u;
Term nextTotal = new Term(sum);
nextTotal.addChild(u);
StateTransition c3_history_transition = new StateTransition();
c3_history_transition.setCurStateExpression(h);
c3_history_transition.setMessageExpression(c3_message);
c3_history_transition.setNextStateExpression(nextHistory2);
c3_history.setStateTransition(c3_history_transition);
StateTransition c3_total_transition = new StateTransition();
c3_total_transition.setCurStateExpression(t);
c3_total_transition.setMessageExpression(c3_message);
c3_total_transition.setNextStateExpression(nextTotal);
c3_total.setStateTransition(c3_total_transition);
System.out.println(c3);
try {
String[] sideEffects = new String[] {""};
System.out.println("-----");
System.out.println(c3.deriveUpdateExpressionOf(c3_total).toImplementation(sideEffects));
System.out.println("-- PUSH --");
Expression totalPushUpdate = c3.deriveUpdateExpressionOf(c3_total, pushAccessor).getKey();
Parameter param = null;
for (Parameter p: totalPushUpdate.getSubTerms(Parameter.class).values()) {
if (p.equals(pPayment) || p.equals(pPoints) || p.equals(pHistory) || p.equals(pTotal)) {
param = p;
break;
}
}
System.out.println("void update(" + param.getType().getImplementationTypeName() + " " + param.toImplementation(sideEffects) + ") {");
System.out.println("\t" + fTotal + " = " + totalPushUpdate.toImplementation(sideEffects) + ";");
System.out.println("}");
System.out.println("-- PULL --");
System.out.println(total.getResourceStateType().getImplementationTypeName() + " " + totalGetter.toImplementation() + "() {");
System.out.println("\t return " + c3.deriveUpdateExpressionOf(c3_total, pullAccessor).getKey().toImplementation(sideEffects) + ";");
System.out.println("}");
} catch (ParameterizedIdentifierIsFutureWork | ResolvingMultipleDefinitionIsFutureWork | InvalidMessage
| UnificationFailed | ValueUndefined e) {
e.printStackTrace();
}
System.out.println("==========");
}
}