diff --git a/include/rosa/agent/State.hpp b/include/rosa/agent/State.hpp index b59f09b..709824b 100644 --- a/include/rosa/agent/State.hpp +++ b/include/rosa/agent/State.hpp @@ -1,115 +1,128 @@ //===-- rosa/agent/State.hpp ----------------------------*- C++ -*-===// // // The RoSA Framework // //===----------------------------------------------------------------------===// /// /// \file rosa/agent/State.hpp /// /// \author Maximilian Götzinger (maximilian.goetzinger@tuwien.ac.at) /// /// \date 2019 /// /// \brief Definition of *state* *functionality*. /// //===----------------------------------------------------------------------===// #ifndef ROSA_AGENT_STATE_HPP #define ROSA_AGENT_STATE_HPP #include "rosa/agent/Functionality.h" #include "rosa/agent/History.hpp" namespace rosa { namespace agent { /// \tparam DIN type of data of input, \tparam DDAB type of data in which DABs are saved, /// \tparam DOUT type of data of abstracted value template class State : public Functionality { private: + unsigned int StateId; + DynamicHistory SampleHistory; DynamicHistory DAB; DynamicHistory DABHistory; - std::shared_ptr> ConfidenceSimilarToSample; - std::shared_ptr> ConfidenceDifferentToSample; + std::shared_ptr> PartialFunctionSampleMatches; + std::shared_ptr> PartialFunctionSampleMismatches; + std::shared_ptr> PartialFunctionNumOfSamplesMatches; + std::shared_ptr> PartialFunctionNumOfSamplesMismatches; bool StateIsValid; bool StateIsValidAfterReentrance; public: - State(unsigned int sampleHistorySize, unsigned int DABSize, - unsigned int DABHistorySize, PartialFunction* ConfidenceSimilarToSample, - PartialFunction* ConfidenceDifferentToSample) noexcept : + State(unsigned int StateId, unsigned int sampleHistorySize, unsigned int DABSize, + unsigned int DABHistorySize, PartialFunction* PartialFunctionSampleMatches, + PartialFunction* PartialFunctionSampleMismatches, + PartialFunction* PartialFunctionNumOfSamplesMatches, + PartialFunction* PartialFunctionNumOfSamplesMismatches) noexcept : SampleHistory(sampleHistorySize), DAB(DABSize), DABHistory(DABHistorySize) { - this->ConfidenceSimilarToSample = ConfidenceSimilarToSample; - this->ConfidenceDifferentToSample = ConfidenceDifferentToSample; + this->StateId = StateId; + this->PartialFunctionSampleMatches = PartialFunctionSampleMatches; + this->PartialFunctionSampleMismatches = PartialFunctionSampleMismatches; + this->PartialFunctionNumOfSamplesMatches = PartialFunctionNumOfSamplesMatches; + this->PartialFunctionNumOfSamplesMismatches = PartialFunctionNumOfSamplesMismatches; StateIsValid = false; StateIsValidAfterReentrance = false; } //TODO: static assert -> check: // 1) if DIN == arithmetic, // 2) if DDAB == float, double, ...? // 3) output could be arithemtic or char/string, right? ~State(void) = default; void leaveState(void) { + //QUESTION: is it important to check first if DAB is empty? if(!DAB.empty()) { - //TODO: delete all entries in DAB - //@Benedikt:I would need such a method in history + DAB.clear(); } StateIsValidAfterReentrance = false; } bool insertSample(D Sample) { bool workedForAll; workedForAll = SampleHistory.addEntry(Sample); + //QUESTION: is it important to have this flag (workedForAll). What should I do if it does not work at some point? if (workedForAll) { - workedForAll &= DAB.addEntry(Sample); if (workedForAll) { if (numberOfEntries >= DAB) { - //TODO: calculate average of DAB - //@Benedikt: should we do this avg calc in the history class or here or somewhere else? - AvgOfDAB = 0; //XXX - Dummy value - + DOUT AvgOfDAB = template average(); + workedForAll &= DABHistory.addEntry(AvgOfDAB); if(workedForAll) { - //TODO: delete all entries in DAB - } //xxx - what should be done if it has not worked? + DAB.clear(); + } //QUESTION: - what should be done if it has not worked? } if(workedForAll) { - //TODO: calculate if state is valid + //TODO: calculate whether state is valid } } } return workedForAll; } - DOUT sampleIsRelatedToState(DIN sample){ - //TODO: check with fuzzyFunctions + DOUT confSampleMatchesState (DIN sample) { + + } - + DOUT confSampleMismatchesState () { + + + } + + unsigned int stateId(void) { return StateId; } }; } // End namespace agent } // End namespace rosa #endif // ROSA_AGENT_STATE_HPP \ No newline at end of file diff --git a/include/rosa/agent/StateDetector.hpp b/include/rosa/agent/StateDetector.hpp index 14f3d87..e91f00f 100644 --- a/include/rosa/agent/StateDetector.hpp +++ b/include/rosa/agent/StateDetector.hpp @@ -1,45 +1,190 @@ //===-- rosa/agent/StateDetector.hpp ----------------------------*- C++ -*-===// // // The RoSA Framework // //===----------------------------------------------------------------------===// /// /// \file rosa/agent/StateDetector.hpp /// /// \author Maximilian Götzinger (maximilian.goetzinger@tuwien.ac.at) /// /// \date 2019 /// /// \brief Definition of *state detection* *functionality*. /// //===----------------------------------------------------------------------===// #ifndef ROSA_AGENT_STATEDETECTOR_HPP #define ROSA_AGENT_STATEDETECTOR_HPP #include "rosa/agent/Functionality.h" +#include "rosa/agent/State.hpp" namespace rosa { namespace agent { -/// A special \c rosa::Agent with its own state. XXX -template class StateDetector : public Functionality { + +//DIN = Input Datatype, CONF = Confidence Datatype +template class StateDetector : public Functionality { private: unsigned int discreteAveragePartitionCounter; + vector DetectedStates; + bool stateIsValid; bool stateIsValidAfterReentrance; + PartialFunction ConfidenceSimilarToSample; + State *ActualState; + + unsigned int SampleHistorySize; + unsigned int DABSize; + unsigned int DABHistorySize; + + std::shared_ptr> PartialFunctionSampleMatches; + std::shared_ptr> PartialFunctionSampleMismatches; + std::shared_ptr> PartialFunctionNumOfSamplesMatches; + std::shared_ptr> PartialFunctionNumOfSamplesMismatches; + + //QUESTION: Do we need the following to flag + bool StateHasChanged; + + //QUESTION: Would this be better as a static variable in State.hpp (there would be the problem when deleting a state) + unsigned int StateIdCounter = 1; + public: + + //TODO: finish constructor + StateDetector() noexcept { + + ActualState = NULL; + + } + + + + + + + + unsigned int detectState (DIN Sample) { + if(ActualState == NULL && DetectedStates.empty()) { + + if(State *S = createNewState()) { + + ActualState = S; + + } //QUESTION: should there an output (log) when it was not successfull? + } + else { + CONF ConfidenceSampleMatchesState = + ActualState->confSampleMatchesState(Sample); + CONF ConfidenceSampleMismatchesState = + ActualState->confSampleMismatchesState(Sample); + + if(ConfidenceSampleMatchesState > ConfidenceSampleMismatchesState) { + + StateHasChanged = false; + + } + else { + + StateHasChanged = true; + + for(auto &SavedState : DetectedStates) { + + if(SavedState != ActualState) { + CONF ConfidenceSampleMatchesState = + SavedState->confSampleMatchesState(Sample); + CONF ConfidenceSampleMismatchesState = + SavedState->confSampleMismatchesState(Sample); + + if(ConfidenceSampleMatchesState > ConfidenceSampleMismatchesState) { + + //TODO: check whether ActiveState is valid + //TODO: if invalid -> deleteState and decrease StateIdCounter + + //QUESTION: maybe it would be better to compare ConfidenceSampleMatchesState + //of all states in the vector + ActualState = SavedState; + + break; + } + } + } + } + } + + ActualState->insertSample(Sample); + + //TODO: check actual state whether it drifts + + return ActualState->stateId; + + } + + + + + + bool stateHasChanged(void) { + return StateHasChanged; + } + + + bool stateIsUnchanged(void) { + return !StateHasChanged; + } + + + + + +private: + + State* createNewState(){ + bool CreatingWorked; + + State *S = new (nothrow) State(StateIdCounter, SampleHistorySize, DABSize, + DABHistorySize, PartialFunctionSampleMatches, + PartialFunctionSampleMismatches, + PartialFunctionNumOfSamplesMatches, + PartialFunctionNumOfSamplesMismatches); + + if(S) { + DetectedStates.push_back(S); //QUESTION: how to make this without any exception? + + CreatingWorked = true; + //TODO: if push_back did not work -> CreatingWorked = false; + } + else { + delete S; + + CreatingWorked = false; + } + + if(CreatingWorked) { + + StateIdCounter++; + + return S; + } + else { + return NULL; + } + } + + + }; } // End namespace agent } // End namespace rosa #endif // ROSA_AGENT_STATEDETECTOR_HPP \ No newline at end of file