diff --git a/build.gradle b/build.gradle index db9f3380a3a243bc376cd56697d83fb4c37febbe..ae22d051ebfedf9a99740f119d21ae32b995f224 100644 --- a/build.gradle +++ b/build.gradle @@ -93,7 +93,7 @@ task ragConnect(type: JavaExec) { '--logReads', '--logWrites', '--verbose', - '--rootNode=A', + '--rootNode=Root', '--incremental=param,debug', "--tracing=cache,flush" ]) diff --git a/libs/relast.jar b/libs/relast.jar index b1a7542048dd1611db7f479307b0285efd8bb1f6..d54fee6e9cedf558f2630db72c2c67533e7c2a02 100644 Binary files a/libs/relast.jar and b/libs/relast.jar differ diff --git a/src/main/jastadd/MinimalModel.connect b/src/main/jastadd/MinimalModel.connect index c7f1af635e09d9b999c72930ae2a1e70639a24ac..1015d1ee1e1343b9107ec9cf328a6425c48fac79 100644 --- a/src/main/jastadd/MinimalModel.connect +++ b/src/main/jastadd/MinimalModel.connect @@ -1,3 +1,4 @@ +// --- simple case --- receive A.Input ; send A.OutputOnA ; send B.OutputOnB using Transformation ; @@ -14,3 +15,7 @@ Transformation maps String s to String {: A.OutputOnA canDependOn A.Input as dependencyA ; B.OutputOnB canDependOn A.Input as dependencyB ; C.OutputOnC canDependOn A.Input as dependencyC ; + +// --- relational case --- +send tree SenderRoot.Alfa ; +receive tree ReceiverRoot.Alfa ; diff --git a/src/main/jastadd/MinimalModel.jrag b/src/main/jastadd/MinimalModel.jrag index c684edbe07795bb53e1131bdbaf533cd584da553..41315d6c159c63b7ee136693ec4afec62345e2ed 100644 --- a/src/main/jastadd/MinimalModel.jrag +++ b/src/main/jastadd/MinimalModel.jrag @@ -10,4 +10,46 @@ aspect Computation { eq A.getC().input() = getInput(); syn D A.getD() = new D().setID("dd" + getInput()); + syn Alfa SenderRoot.getAlfa() { + Alfa result = new Alfa(); + for (int i = 0; i < 4; i++) { + result.addEcho(new Echo().setID(i)); + result.addFoxtrot(new Foxtrot().setID(i)); + result.addGolf(new Golf().setID(i)); + } + // rel Alfa.MyBravo -> Bravo ; + result.setMyBravo(getBravo(getInput())); + // rel Alfa.MultiBravo* -> Bravo ; + result.addMultiBravo(getBravo(getInput())); + result.addMultiBravo(getBravo((getInput() + 1))); + + // rel Alfa.MidiDelta <-> Delta.MidiAlfa? ; + result.setMidiDelta(getDelta(getInput())); + + // rel Alfa.MyEcho -> Echo ; + result.setMyEcho(result.getEcho(getInput())); + // rel Alfa.MultiEcho* -> Echo ; + result.addMultiEcho(result.getEcho(getInput())); + result.addMultiEcho(result.getEcho(getInput() + 1)); + + // rel Foxtrot.MyAlfa? -> Alfa ; + result.getFoxtrot(getInput()).setMyAlfa(result); + + // rel Alfa.MidiGolf <-> Golf.MidiAlfa? ; + result.setMidiGolf(result.getGolf(getInput())); + + // rel Alfa.MyHotel -> Hotel ; + result.setMyHotel(getSenderSubTree().getHotel(getInput())); + // rel Alfa.MultiHotel* -> Hotel ; + result.addMultiHotel(getSenderSubTree().getHotel(getInput())); + result.addMultiHotel(getSenderSubTree().getHotel((getInput() + 1))); + return result; + } +} + +aspect NameResolution { + @Override + protected String Nameable.customID() { + return getClass().getSimpleName() + getID(); + } } diff --git a/src/main/jastadd/MinimalModel.relast b/src/main/jastadd/MinimalModel.relast index 1df3cc07e098d21ac34238697ba7afdeecdd5067..f5852950d9a9d0d99c84070ae4cfd429760510cd 100644 --- a/src/main/jastadd/MinimalModel.relast +++ b/src/main/jastadd/MinimalModel.relast @@ -1,4 +1,36 @@ +Root ::= A* SenderRoot* ReceiverRoot* ; + A ::= <Input:String> /<OutputOnA:String>/ B* C* /D/ Reading:D ; B ::= /<OutputOnB:String>/ ; C ::= /<OutputOnC:String>/ ; D ::= <ID:String> ; + +Nameable ::= <ID:int> ; +SenderRoot : Nameable ::= <Input:int> /Alfa/ Bravo* Charlie* Delta* SenderSubTree ; +SenderSubTree : Nameable ::= Hotel* ; + +ReceiverRoot : Nameable ::= Alfa Bravo* Charlie* Delta* ReceiverSubTree ; +ReceiverSubTree : Nameable ::= Hotel* ; + +Alfa : Nameable ::= Echo* Foxtrot* Golf* ; + +Bravo : Nameable ; +Charlie : Nameable ; +Delta : Nameable ; +Echo : Nameable ; +Foxtrot : Nameable ; +Golf : Nameable ; +Hotel : Nameable ; + +rel Alfa.MyBravo -> Bravo ; +rel Alfa.MultiBravo* -> Bravo ; +// # relation into NTA not possible +//rel Charlie.MyAlfa -> Alfa ; +// # bidi relation from/into NTA probably not a good idea +rel Alfa.MidiDelta <-> Delta.MidiAlfa? ; +rel Alfa.MyEcho -> Echo ; +rel Alfa.MultiEcho* -> Echo ; +rel Foxtrot.MyAlfa? -> Alfa ; +rel Alfa.MidiGolf <-> Golf.MidiAlfa? ; +rel Alfa.MyHotel -> Hotel ; +rel Alfa.MultiHotel* -> Hotel ; diff --git a/src/main/java/de/tudresden/inf/st/mrc/MinimalMain.java b/src/main/java/de/tudresden/inf/st/mrc/MinimalMain.java index 542ff536c5571c748dfd31e3ed012070a855a46f..d29074e58a857b2c0463eb1915a005239eaaffcc 100644 --- a/src/main/java/de/tudresden/inf/st/mrc/MinimalMain.java +++ b/src/main/java/de/tudresden/inf/st/mrc/MinimalMain.java @@ -9,6 +9,8 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.file.Paths; import java.time.Instant; +import java.util.List; +import java.util.stream.Collectors; import static java.util.concurrent.TimeUnit.SECONDS; @@ -17,6 +19,7 @@ import static java.util.concurrent.TimeUnit.SECONDS; * * @author rschoene - Initial contribution */ +@SuppressWarnings("CommentedOutCode") public class MinimalMain { private static final Logger logger = LogManager.getLogger(MinimalMain.class); private static final String TOPIC_FOR_INPUT = "topic/for/input"; @@ -52,7 +55,8 @@ public class MinimalMain { publisher.publish("---", ("Start at " + Instant.now()).getBytes()); // mainIncremental(); - mainTree(); +// mainSimpleTree(); + mainRelationalTree(); } private static void mainIncremental() throws Exception { @@ -189,15 +193,18 @@ public class MinimalMain { logger.info("result.getD().getID() = " + result.getD().getID()); } - private static void mainTree() throws IOException, InterruptedException { + private static void mainSimpleTree() throws IOException, InterruptedException { String uriString = "mqtt://localhost/normalA/d/out"; + Root root = new Root(); + root.ragconnectSetupMqttWaitUntilReady(2, SECONDS); + A sender = new A(); + root.addA(sender); sender.setInput("123"); - sender.ragconnectSetupMqttWaitUntilReady(2, SECONDS); A receiver = new A(); - receiver.ragconnectSetupMqttWaitUntilReady(2, SECONDS); + root.addA(receiver); receiver.connectReading(uriString); sender.connectOutputOnA("mqtt://localhost/normalA/out", true); @@ -215,6 +222,121 @@ public class MinimalMain { logger.info("receiver.getReading().getID() = " + receiver.getReading().getID()); } + private static void mainRelationalTree() throws IOException, InterruptedException { + final String mqttUriString = "mqtt://localhost/alfa"; + + Root root1ForSender = new Root(); + root1ForSender.ragconnectSetupMqttWaitUntilReady(2, SECONDS); + + SenderRoot senderRoot = createSenderRoot(); + root1ForSender.addSenderRoot(senderRoot); + senderRoot.connectAlfa(mqttUriString, false); + + Root root2ForReceiver = new Root(); + root2ForReceiver.ragconnectSetupMqttWaitUntilReady(2, SECONDS); + ReceiverRoot receiverRoot = createReceiverRoot(); + root2ForReceiver.addReceiverRoot(receiverRoot); + receiverRoot.connectAlfa(mqttUriString); + + senderRoot.setInput(1); + describedWait(1, "after setting input to 1"); + printSender(senderRoot); + printReceiver(receiverRoot); + + senderRoot.setInput(2); + describedWait(1, "after setting input to 2"); + printSender(senderRoot); + printReceiver(receiverRoot); + } + + private static void printSender(SenderRoot senderRoot) { + printAlfa("sender", senderRoot.getAlfa(), senderRoot::getDeltaList); + } + + private static void printReceiver(ReceiverRoot receiverRoot) { + printAlfa("receiver", receiverRoot.getAlfa(), receiverRoot::getDeltaList); + } + + private static SenderRoot createSenderRoot() { + SenderRoot result = new SenderRoot(); + SenderSubTree subTree = new SenderSubTree(); + result.setSenderSubTree(subTree); + templateCreation(result::addBravo, result::addCharlie, result::addDelta, subTree::addHotel); + return result; + } + + private static ReceiverRoot createReceiverRoot() { + ReceiverRoot result = new ReceiverRoot(); + ReceiverSubTree subTree = new ReceiverSubTree(); + result.setReceiverSubTree(subTree); + templateCreation(result::addBravo, result::addCharlie, result::addDelta, subTree::addHotel); + return result; + } + + private static void templateCreation(AddBravo addBravo, AddCharlie addCharlie, AddDelta addDelta, AddHotel addHotel) { + for (int i = 0; i < 4; i++) { + addBravo.accept(new Bravo(i)); + addCharlie.accept(new Charlie(i)); + addDelta.accept(new Delta(i)); + addHotel.accept(new Hotel(i)); + } + } + + interface AddBravo { void accept(Bravo b); } + interface AddCharlie { void accept(Charlie b); } + interface AddDelta { void accept(Delta b); } + interface GetDeltaList { Iterable<Delta> get(); } + interface AddHotel { void accept(Hotel b); } + + private static void printAlfa(String name, Alfa alfa, GetDeltaList getDeltaList) { + StringBuilder sbDelta = new StringBuilder(); + for (Delta delta : getDeltaList.get()) { + sbDelta.append(delta.getID()) + .append("->") + .append(delta.hasMidiAlfa() ? delta.getMidiAlfa().getID() : "/") + .append(", "); + } + String deltaList = sbDelta.toString(); + StringBuilder sbFoxtrot = new StringBuilder(); + for (Foxtrot foxtrot : alfa.getFoxtrotList()) { + sbFoxtrot.append(foxtrot.getID()) + .append("->") + .append(foxtrot.hasMyAlfa() ? foxtrot.getMyAlfa().getID() : "/") + .append(", "); + } + String foxtrotList = sbFoxtrot.toString(); + logger.info("Checking Alfa\n" + + "{}: {} in {}\n" + + " |- MyBravo: {}\n" + + " |- MultiBravoList: {}\n" + + " |- MidiDelta: {} (MidiDelta.getMidiAlfa(): {})\n" + + " |- DeltaList: {}\n" + + " |- MyEcho: {}\n" + + " |- MultiEchoList: {}\n" + + " |- FoxtrotList (id -> alfa.id): {}\n" + + " |- MidiGolf: {} (MidiGolf.getMidiAlfa(): {})\n" + + " |- MyHotel: {}\n" + + " |- MultiHotelList: {}" + + "{}", // just to make swapping of params easier (all have a comma at the end) + name, alfa, alfa.getParent(), + alfa.getMyBravo().getID(), + printNameableList(alfa.getMultiBravoList()), + alfa.getMidiDelta().getID(), alfa.getMidiDelta().getMidiAlfa(), + deltaList, + alfa.getMyEcho().getID(), + printNameableList(alfa.getMultiEchoList()), + foxtrotList, + alfa.getMidiGolf().getID(), alfa.getMidiGolf().getMidiAlfa(), + alfa.getMyHotel().getID(), + printNameableList(alfa.getMultiHotelList()), + "" + ); + } + + private static String printNameableList(List<? extends Nameable> nameableList) { + return nameableList.stream().map(nameable -> Integer.toString(nameable.getID())).collect(Collectors.joining(",", "[", "]")); + } + // private static void enableTracing(ASTNode<?> node) { // if (node.trace().getReceiver() != null && node.trace().getReceiver() instanceof MinimalReceiver) {