-
Ludovic Apvrille authoredLudovic Apvrille authored
AIStateMachine.java 8.85 KiB
/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille
*
* ludovic.apvrille AT enst.fr
*
* This software is a computer program whose purpose is to allow the
* edition of TURTLE analysis, design and deployment diagrams, to
* allow the generation of RT-LOTOS or Java code from this diagram,
* and at last to allow the analysis of formal validation traces
* obtained from external tools, e.g. RTL from LAAS-CNRS and CADP
* from INRIA Rhone-Alpes.
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL license and that you accept its terms.
*/
package ai;
import avatartranslator.AvatarBlock;
import avatartranslator.AvatarSpecification;
import avatartranslator.tosysmlv2.AVATAR2SysMLV2;
import myutil.TraceManager;
import org.apache.batik.anim.timing.Trace;
import java.util.ArrayList;
/**
* Class AIStateMachine
* <p>
* Creation: 02/06/2023
*
* @author Ludovic APVRILLE
* @version 1.0 13/06/2023
*/
public class AIStateMachine extends AIInteract implements AISysMLV2DiagramContent, AIAvatarSpecificationRequired {
private static String[] SUPPORTED_DIAGRAMS = {"BD"};
private static String[] EXCLUSIONS_IN_INPUT = {"state", "method"};
public static String KNOWLEDGE_ON_JSON_FOR_STATE_MACHINES = "When you are asked to identify the SysML state machine of a block, " +
"return them as a JSON specification " +
"formatted as follows:" +
"{states: [{ \"name\": \"Name of state\", transitions [{ \"destinationstate\" : \"state name\", \"guard\": \"boolean condition\", " +
"\"after\": \"time " +
"value\", \"action\":" +
" \"attribute action or signal receiving/sending\"}]}]} ." +
"# Respect: in actions, use only attributes and signals already defined in the corresponding block" +
"# Respect: at least one state must be called \"Start\", which is the start state" +
"# Respect: if a guard, an action, or an after is empty, use an empty string \"\", do not use \"null\"" +
"# Respect: an action contains either a variable affectation, e.g. \"x = x + 1\" or a signal send/receive " +
"# Respect: if a transition contains several actions, use a \";\" to separate them " +
"# Respect: a signal send is out::signalName(..) and a signal receive is in::signaNamd(...) " +
"# Respect: the attribute of an action is named by its identifier, do not reference its block " +
"# Respect: a state machine can use only the attribute of its block " +
"# Respect: A guard cannot contain a reference to a signal " +
"# Respect: To reference the attribute \"x\" of block \"B\", use \"x\" and never \"B.x\" nor \"B::x\"";
private AvatarSpecification specification;
private String diagramContentInSysMLV2;
private static String KNOWLEDGE_SYSTEM_SPECIFICATION = "The specification of the system is:";
private static String KNOWLEDGE_SYSTEM_BLOCKS = "The specification of the blocks in SysML V2 is:";
private String[] QUESTION_IDENTIFY_STATE_MACHINE = {"From the system specification, and from the definition of blocks and" +
" their " +
"connections, identify the state machine of block: "};
public AIStateMachine(AIChatData _chatData) {
super(_chatData);
}
public void internalRequest() {
// Add the knowledge, retrieve the block names, attributes, etc.
initKnowledge();
/*if (!chatData.knowledgeOnStateMachines) {
chatData.aiinterface.addKnowledge(KNOWLEDGE_ON_JSON_FOR_STATE_MACHINES, "ok");
chatData.knowledgeOnStateMachines = true;
}
chatData.aiinterface.addKnowledge(KNOWLEDGE_SYSTEM_SPECIFICATION + chatData.lastQuestion, "ok");
chatData.aiinterface.addKnowledge(KNOWLEDGE_SYSTEM_BLOCKS + diagramContentInSysMLV2, "ok");*/
// Getting block names for SysMLV2 spec
//TraceManager.addDev("SysML V2 spec: " + diagramContentInSysMLV2);
ArrayList<String> blockNames = AVATAR2SysMLV2.getAllBlockNames(diagramContentInSysMLV2);
TraceManager.addDev("Going to handle the following blocks: ");
for(String s: blockNames) {
TraceManager.addDev("\tblock: " + s);
}
boolean done = false;
int cpt = 0;
String questionT;
for(String blockName: blockNames) {
TraceManager.addDev("Handling block: " + blockName);
done = false; cpt = 0;
int max = 10;
questionT = QUESTION_IDENTIFY_STATE_MACHINE[0] + blockName;
while (!done && cpt < max) {
done = true;
boolean ok = makeQuestion(questionT);
if (!ok) {
TraceManager.addDev("Make question failed");
}
if (ok && specification != null) {
AvatarBlock b = specification.getBlockWithName(blockName);
if (b != null) {
TraceManager.addDev("Making the state machine of " + blockName);
ArrayList<String> errors = b.makeStateMachineFromJSON(extractJSON(), cpt == (max - 1));
if ((errors != null) && (errors.size() > 0)) {
done = false;
questionT = "Your answer was not correct because of the following errors:";
for (String s : errors) {
TraceManager.addDev("Error in JSON: " + s);
questionT += "\n- " + s;
}
} else {
TraceManager.addDev("SMD done for Block " + blockName);
}
} else {
TraceManager.addDev("ERROR: no block named " + blockName);
}
} else {
TraceManager.addDev("Null specification or false ok");
}
waitIfConditionTrue(!done && cpt < max);
cpt ++;
}
// Remove knowledge of previous questions
initKnowledge();
/*while(cpt > 0) {
cpt --;
chatData.aiinterface.removePreviousKnowledge();
}*/
}
TraceManager.addDev("Reached end of AIStateMachine internal request cpt=" + cpt);
}
private void initKnowledge() {
chatData.aiinterface.clearKnowledge();
chatData.aiinterface.addKnowledge(KNOWLEDGE_ON_JSON_FOR_STATE_MACHINES, "ok");
chatData.aiinterface.addKnowledge(KNOWLEDGE_SYSTEM_SPECIFICATION + chatData.lastQuestion, "ok");
chatData.aiinterface.addKnowledge(KNOWLEDGE_SYSTEM_BLOCKS + diagramContentInSysMLV2, "ok");
}
public Object applyAnswer(Object input) {
TraceManager.addDev("Apply answer in AIState Machine");
if (specification == null) {
TraceManager.addDev("Null spec");
} else {
TraceManager.addDev("Non null spec");
}
if (input == null) {
return specification;
}
return specification;
}
public void setAvatarSpecification(AvatarSpecification _specification) {
specification = _specification;
};
public void setDiagramContentInSysMLV2(String _diagramContentInSysMLV2) {
diagramContentInSysMLV2 = _diagramContentInSysMLV2;
};
public String[] getValidDiagrams() {
return SUPPORTED_DIAGRAMS;
}
public String[] getDiagramExclusions() {
return EXCLUSIONS_IN_INPUT;
}
}