diff --git a/src/main/java/ai/AIBlock.java b/src/main/java/ai/AIBlock.java index a9fab30ec3e94c63e052961994386bbcc9d8dee9..c18359d9855ed157f656e36664d4a9120cc4bd76 100644 --- a/src/main/java/ai/AIBlock.java +++ b/src/main/java/ai/AIBlock.java @@ -64,12 +64,18 @@ public class AIBlock extends AIInteract { "Use only attributes of type int or boolean. If you want to use \"String\" or another other attribute, use int." + "# Respect: each attribute must be of type \"int\" or \"bool\" only" + "# Respect: Any identifier (block, attribute, etc.) must no contain any space. Use \"_\" instead."; - public static String KNOWLEDGE_ON_JSON_FOR_BLOCKS_AND_CONNECTIONS = "When you are ask to identify signals of blocks, give a name to each " + - "signal, and input/output direction and list their attributes. Also, each signal must be connected with exactly one" + - " signal. For instance, if block b1 has a signal \"output s1(int x)\", and b2 a signal \"input s2(int y)\", s1 and s2 " + - "can be connected. In " + - "JSON, signals are given in the definition of blocks. JSON is as follows: {blocks: [{ \"name\": \"Name of block\", \"signals\": " + - "[\"signal\": \"input/output sig1(int x, bool b)\"] (no need to relist the attributes of signals, nor to give a direction) and after " + + public static String KNOWLEDGE_ON_JSON_FOR_BLOCKS_AND_CONNECTIONS = "When you are ask to identify signals of blocks, JSON is as follows: " + + "{blocks: [{ \"name\": \"Name of block\", \"signals\": " + + "[ ... signals ... ] ... (no need to relist the attributes of signals, nor to give a direction). " + + "#Respect: signals are defined like this in JSON: {\"signal\": \"input sig1(int x, bool b)\"} if the signal is an input signal" + + " and {\"signal\": \"output sig1(int x, bool b)\"} if the signal is an output signal" + + "#Respect 2 signals with the same name are assumed to be connected: this is the only way to connect signals. " + + "#Respect: Two connected signals must have " + + "the same list of attributes, even if they are " + + "defined in two different blocks. One of them must be output, the other one must be input" + + "#Respect: all input signals must have exactly one corresponding output signal, i.e. a signal with the same name" + + "#Respect: two signals with the same name must be defined in different blocks"; + /*"and after " + "the blocks, add the " + "following JSON: " + "connections: [{\"block1\" : name of first block, \"sig1\": name of first " + @@ -80,7 +86,8 @@ public class AIBlock extends AIInteract { "\"input\" nor " + "\"output\", nor its attributes.#" + "Two connected signals must have the \" +\n" + - " \"same list of attributes."; + " \"same list of attributes." + + "# A signal must be involved in one connection exactly";*/ @@ -88,9 +95,10 @@ public class AIBlock extends AIInteract { public static String[] KNOWLEDGE_STAGES = {KNOWLEDGE_ON_JSON_FOR_BLOCKS_AND_ATTRIBUTES, KNOWLEDGE_ON_JSON_FOR_BLOCKS_AND_CONNECTIONS}; AvatarSpecification specification; private String[] QUESTION_IDENTIFY_SYSTEM_BLOCKS = {"From the following system specification, using the specified JSON format, identify the " + - "typical system blocks and their attributes. Do respect the JSON format.\n", "From the previous JSON and system specification, update " + + "typical system blocks and their attributes. Do respect the JSON format, and provide only JSON (no explanation before or after).\n", + "From the previous JSON and system specification, update " + "this JSON with" + - " the signals and connection between signals."}; + " the signals you have to identify. If necessary, you can add new blocks and new attributes."}; public AIBlock(AIChatData _chatData) { @@ -122,9 +130,10 @@ public class AIBlock extends AIInteract { errors = AvatarSpecification.getJSONErrors(); } catch (org.json.JSONException e) { - TraceManager.addDev("Invalid JSON spec: " + extractJSON() + " because " + e.getMessage()); + TraceManager.addDev("Invalid JSON spec: " + extractJSON() + " because " + e.getMessage() + ": INJECTING ERROR"); errors = new ArrayList<>(); - errors.add("There is an error in your JSON: " + e.getMessage() + ". probably the JSON spec was incomplete. Do correct it"); + errors.add("There is an error in your JSON: " + e.getMessage() + ". probably the JSON spec was incomplete. Do correct it. I need " + + "the full specification at once."); } if ((errors != null) && (errors.size() > 0)) { @@ -147,7 +156,7 @@ public class AIBlock extends AIInteract { cpt++; } - TraceManager.addDev("Reached end og AIBlock internal request"); + TraceManager.addDev("Reached end of AIBlock internal request cpt=" + cpt); } diff --git a/src/main/java/avatartranslator/AvatarBlock.java b/src/main/java/avatartranslator/AvatarBlock.java index 560fce092e60e88bc05b422817186873a020f063..1d44368b2dbc945e3d5a1c3ce0d3fae66cb1fc90 100644 --- a/src/main/java/avatartranslator/AvatarBlock.java +++ b/src/main/java/avatartranslator/AvatarBlock.java @@ -537,6 +537,12 @@ public class AvatarBlock extends AvatarElement implements AvatarStateMachineOwne return (asme != null); } + public void removeAvatarSignal(AvatarSignal as) { + if (signals.contains(as)) { + signals.remove(as); + } + } + public void removeTimers(AvatarSpecification _spec, List<AvatarBlock> _addedBlocks) { AvatarSignal asSet, asReset, asExpire; String name; diff --git a/src/main/java/avatartranslator/AvatarSignal.java b/src/main/java/avatartranslator/AvatarSignal.java index af4a11ca6170a9ab012419ac821c9a019a04ada7..5c664cc9b5ad4bdd043028e62a3c3e6086d217a1 100644 --- a/src/main/java/avatartranslator/AvatarSignal.java +++ b/src/main/java/avatartranslator/AvatarSignal.java @@ -206,7 +206,7 @@ public class AvatarSignal extends AvatarMethod { //TraceManager.addDev("SignalName: " + signalName + " signal:" + signal); if (!isAValidId(signalName, true, true,true, false)) { - TraceManager.addDev("Unvalid id of signal " + signalName); + TraceManager.addDev("Invalid id of signal " + signalName); return null; } @@ -261,11 +261,11 @@ public class AvatarSignal extends AvatarMethod { return null; } if (!isAValidId(splitted[i], false, false,false, true)) { - TraceManager.addDev("Unvalid type: " + splitted[i]); + TraceManager.addDev("Invalid type: " + splitted[i]); return null; } if (!isAValidId(splitted[i + 1], true, true,true, false)) { - TraceManager.addDev("Unvalid id of parameter " + splitted[i + 1]); + TraceManager.addDev("Invalid id of parameter " + splitted[i + 1]); return null; } //TraceManager.addDev("Adding parameter: " + splitted[i] + " " + splitted[i+1]); diff --git a/src/main/java/avatartranslator/AvatarSpecification.java b/src/main/java/avatartranslator/AvatarSpecification.java index 4a76765c7ae5b76647fea998e6e94927032a6858..7cb434b5e8c743679157dcfc42e24fb568be1296 100644 --- a/src/main/java/avatartranslator/AvatarSpecification.java +++ b/src/main/java/avatartranslator/AvatarSpecification.java @@ -624,7 +624,97 @@ public class AvatarSpecification extends AvatarElement implements IBSParamSpec { } } - JSONArray connections = null; + + // Connecting signals with identical names + HashSet<AvatarSignal> signalSet = new HashSet<>(); + HashSet<AvatarSignal> toBeRemoved = new HashSet<>(); + + + // We consider blocks one after the others + // We find signals with the same name in another block + // We connect them if not yet connected + // Signals are updated if their attribute list does not work + // Non connected signals are finally removed + + + + for(AvatarBlock block: spec.getListOfBlocks()) { + for (AvatarSignal outSig: block.getSignals()) { + if (!(signalSet.contains(outSig))) { + if (outSig.isOut()) { + // We look for a similar signal but out + AvatarSignal inSig = spec.getSignalWithNameAndDirection(outSig.getSignalName(), AvatarSignal.IN); + if (inSig == null) { + toBeRemoved.add(outSig); + } else { + if (signalSet.contains(inSig)) { + toBeRemoved.add(outSig); + } else { + + + if (!outSig.isCompatibleWith(inSig)) { + // inSig parameters are used, and the definition of outSig is changed + outSig.getListOfAttributes().clear(); + for(AvatarAttribute aa: inSig.getListOfAttributes()) { + outSig.addParameter(aa.clone()); + } + } + + AvatarBlock destB = spec.getBlockWithSignal(inSig); + if (destB != null) { + AvatarRelation ar = spec.getAvatarRelationWithBlocks(block, destB, true); + + if (ar == null) { + ar = new AvatarRelation("relation", block, destB, _referenceObject); + ar.setAsynchronous(false); + spec.addRelation(ar); + } + + // Signals can be connected + signalSet.add(outSig); + signalSet.add(inSig); + + + // If the signals have the same name and are in the same block ,they are renamed + if ((outSig.getSignalName().compareTo(inSig.getSignalName()) == 0) && (destB == block)) { + outSig.setName(outSig.getSignalName() + "_out"); + inSig.setName(inSig.getSignalName() + "_in"); + } + + ar.addSignals(outSig, inSig); + + TraceManager.addDev("Connecting " + outSig.getSignalName() + " to " + inSig.getSignalName()); + } else { + toBeRemoved.add(outSig); + } + + } + + } + } + } + } + } + + // Identify in signals that are not connected + for(AvatarBlock block: spec.getListOfBlocks()) { + for (AvatarSignal inSig : block.getSignals()) { + if (!(signalSet.contains(inSig))) { + if (inSig.isIn()) { + toBeRemoved.add(inSig); + } + } + } + } + + for(AvatarSignal as: toBeRemoved) { + for (AvatarBlock block : spec.getListOfBlocks()) { + block.removeAvatarSignal(as); + } + } + + + /*JSONArray connections = null; try { connections = mainObject.getJSONArray("connections"); } catch (JSONException je) { @@ -644,21 +734,18 @@ public class AvatarSpecification extends AvatarElement implements IBSParamSpec { continue; } + String srcBlock = spec.removeSpaces(blockO.getString("block1")); String sourceSignal = spec.removeSpaces(blockO.getString("sig1")); + String dstBlock = spec.removeSpaces(blockO.getString("block2")); String destinationSignal = spec.removeSpaces(blockO.getString("sig2")); - if (destinationSignal.compareTo(sourceSignal) == 0) { - jsonErrors.add("Signals must be different in a connection, but the following connection has the same signals: " + sourceSignal); - TraceManager.addDev("Signals must be different in a connection, but the following connection has the same signals: " - + sourceSignal); - continue; - } - AvatarBlock srcB = spec.getBlockWithSignal(sourceSignal); + + AvatarBlock srcB = spec.getBlockWithName(srcBlock); if (srcB == null) { - jsonErrors.add("Signal " + sourceSignal + " does not exist"); - TraceManager.addDev("Signal " + sourceSignal + " does not exist"); + jsonErrors.add("Block " + srcBlock + " does not exist"); + TraceManager.addDev("Block " + srcBlock + " does not exist"); continue; } @@ -677,25 +764,26 @@ public class AvatarSpecification extends AvatarElement implements IBSParamSpec { } - AvatarBlock destB = spec.getBlockWithSignal(destinationSignal); + AvatarBlock destB = spec.getBlockWithName(dstBlock); if (destB == null) { - jsonErrors.add("Signal " + destinationSignal + " does not exist"); - TraceManager.addDev("Signal " + destinationSignal + " does not exist"); + jsonErrors.add("Block " + dstBlock + " does not exist"); + TraceManager.addDev("Block " + dstBlock + " does not exist"); continue; + } AvatarSignal dstSig = destB.getSignalByName(destinationSignal); if (dstSig == null) { TraceManager.addDev("Signal added as in signal: " + destinationSignal); - dstSig = new AvatarSignal(sourceSignal, AvatarSignal.IN, _referenceObject); - destB.addSignal(srcSig); + dstSig = new AvatarSignal(destinationSignal, AvatarSignal.IN, _referenceObject); + destB.addSignal(dstSig); } if (dstSig.isOut()) { - jsonErrors.add("Signal " + destinationSignal + " in block: " + destB.getName() + " should be int"); - TraceManager.addDev("Signal " + destinationSignal + " in block: " + destB.getName() + " should be int"); + jsonErrors.add("Signal " + destinationSignal + " in block: " + destB.getName() + " should be in"); + TraceManager.addDev("Signal " + destinationSignal + " in block: " + destB.getName() + " should be in"); continue; } @@ -709,8 +797,9 @@ public class AvatarSpecification extends AvatarElement implements IBSParamSpec { continue; } - String communicationType = spec.removeSpaces(blockO.getString("communicationType")); - boolean synchronous = communicationType.compareTo("synchronous") == 0; + //String communicationType = spec.removeSpaces(blockO.getString("communicationType")); + //boolean synchronous = communicationType.compareTo("synchronous") == 0; + boolean synchronous = true; AvatarRelation ar = spec.getAvatarRelationWithBlocks(srcB, destB, synchronous); @@ -722,7 +811,7 @@ public class AvatarSpecification extends AvatarElement implements IBSParamSpec { ar.addSignals(srcSig, dstSig); - } + }*/ return spec; @@ -982,6 +1071,26 @@ public class AvatarSpecification extends AvatarElement implements IBSParamSpec { return null; } + public AvatarBlock getBlockWithSignal(AvatarSignal as) { + for(AvatarBlock b: blocks) { + if (b.getSignals().contains(as)){ + return b; + } + } + return null; + } + + public AvatarSignal getSignalWithNameAndDirection(String name, int direction) { + for(AvatarBlock block: blocks) { + for(AvatarSignal as: block.getSignals()) { + if ((as.getSignalName().compareTo(name) == 0) && (as.getInOut() == direction)) { + return as; + } + } + } + return null; + } + public AvatarAMSInterface getAMSInterfaceWithName(String _name) { for (AvatarAMSInterface interf : interfaces) { if (interf.getName().compareTo(_name) == 0) { diff --git a/src/main/java/ui/avatarbd/AvatarBDPanel.java b/src/main/java/ui/avatarbd/AvatarBDPanel.java index c091745b193286e60f22b311e501b2c16bed2fd4..14a085f16f292472f14cae31cb9d45b8a6d07d02 100644 --- a/src/main/java/ui/avatarbd/AvatarBDPanel.java +++ b/src/main/java/ui/avatarbd/AvatarBDPanel.java @@ -457,11 +457,11 @@ public class AvatarBDPanel extends TDiagramPanel { for (AvatarSignal sig : sigs) { // Try to associate it with one of the signals for (AvatarSignal pot : otherBlock.getListOfAvailableSignals()) { - TraceManager.addDev("Testing block" + block.getBlockName() + " sig=" + sig.getId() + - " with block " + otherBlock.getBlockName() + " sig = " + pot.getId()); + //TraceManager.addDev("Testing block" + block.getBlockName() + " sig=" + sig.getId() + + // " with block " + otherBlock.getBlockName() + " sig = " + pot.getId()); if (sig.isCompatibleWith(pot) && (sig.getId().compareTo(pot.getId()) == 0)) { - TraceManager.addDev("Added connection: block " + block.getBlockName() + " sig=" + sig.getId() + - " with block " + otherBlock.getBlockName() + " sig = " + pot.getId()); + //TraceManager.addDev("Added connection: block " + block.getBlockName() + " sig=" + sig.getId() + + // " with block " + otherBlock.getBlockName() + " sig = " + pot.getId()); port.addSignal(sig.toString(), sig.getInOut() == AvatarSignal.IN, origin); port.addSignal(pot.toString(), pot.getInOut() == AvatarSignal.IN, !origin); diff --git a/src/main/java/ui/window/JFrameAI.java b/src/main/java/ui/window/JFrameAI.java index 8b414b16338ba835d465a36a23aac259bbfb32ff..913d2201947a0b4183b7448146eac0d06060391b 100644 --- a/src/main/java/ui/window/JFrameAI.java +++ b/src/main/java/ui/window/JFrameAI.java @@ -278,7 +278,7 @@ public class JFrameAI extends JFrame implements ActionListener { "macareux", "ours", "italien", "paris-brest", "belle-mère", "apéro (l'abus d'alcool est dangereux pour la santé)", "carpe", "crocodile", "psychologue", "dr emacs", "3615-TTool", "100 balles et 1 mars", "opéra (l’abus d’Alcôve est dangereux pour la santé)", "chapon", "perroquet", "chameau volant", "Alice", "Oasis", "ATC RAK", - "Adibou"}; + "Adibou", "Cheval de Troyes"}; int x = (int) (Math.random() * names.length); return names[x]; }