Page MenuHomePhorge

No OneTemporary

Size
25 KB
Referenced Files
None
Subscribers
None
diff --git a/include/rosa/agent/FunctionAbstractions.hpp b/include/rosa/agent/FunctionAbstractions.hpp
index 59200de..b12ce98 100644
--- a/include/rosa/agent/FunctionAbstractions.hpp
+++ b/include/rosa/agent/FunctionAbstractions.hpp
@@ -1,222 +1,222 @@
//===-- rosa/agent/FunctionAbstractions.hpp ---------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/agent/FunctionAbstractions.hpp
///
/// \author Benedikt Tutzer (benedikt.tutzer@tuwien.ac.at)
///
/// \date 2019
///
/// \brief Definition of *FunctionAbstractions* *functionality*.
///
//===----------------------------------------------------------------------===//
#ifndef ROSA_AGENT_FUNCTIONABSTRACTIONS_HPP
#define ROSA_AGENT_FUNCTIONABSTRACTIONS_HPP
#include "rosa/agent/Abstraction.hpp"
#include "rosa/agent/Functionality.h"
#include "rosa/support/debug.hpp"
#include <algorithm>
#include <cmath>
#include <memory>
#include <vector>
namespace rosa {
namespace agent {
/// Implements \c rosa::agent::Abstraction as a linear function,
/// y = Coefficient * X + Intercept.
///
/// \note This implementation is supposed to be used to represent a linear
/// function from an arithmetic domain to an arithmetic range. This is enforced
/// statically.
///
/// \tparam D type of the functions domain
/// \tparam R type of the functions range
template <typename D, typename R>
class LinearFunction : public Abstraction<D, R> {
// Make sure the actual type arguments are matching our expectations.
STATIC_ASSERT((std::is_arithmetic<D>::value),
"LinearFunction not arithmetic T");
STATIC_ASSERT((std::is_arithmetic<R>::value),
"LinearFunction not to arithmetic");
protected:
/// The Intercept of the linear function
const D Intercept;
/// The Coefficient of the linear function
const D Coefficient;
public:
/// Creates an instance.
///
/// \param Intercept the intercept of the linear function
/// \param Coefficient the coefficient of the linear function
LinearFunction(D Intercept, D Coefficient) noexcept
: Abstraction<D, R>(Intercept), Intercept(Intercept),
Coefficient(Coefficient) {}
/// Destroys \p this object.
~LinearFunction(void) = default;
/// Checks wether the Abstraction evaluates to default at the given position
/// As LinearFunctions can be evaluated everythwere, this is always false
///
/// \param V the value at which to check if the function falls back to it's
/// default value.
///
/// \return false
bool isDefaultAt(const D &V) const noexcept override {
(void)V;
return false;
}
/// Evaluates the linear function
///
/// \param X the value at which to evaluate the function
///
/// \return Coefficient*X + Intercept
virtual R operator()(const D &X) const noexcept override {
return Intercept + X * Coefficient;
}
};
/// Implements \c rosa::agent::Abstraction as a sine function,
/// y = Amplitude * sin(Frequency * X + Phase) + Average.
///
/// \note This implementation is supposed to be used to represent a sine
/// function from an arithmetic domain to an arithmetic range. This is enforced
/// statically.
///
/// \tparam D type of the functions domain
/// \tparam R type of the functions range
template <typename D, typename R>
class SineFunction : public Abstraction<D, R> {
// Make sure the actual type arguments are matching our expectations.
STATIC_ASSERT((std::is_arithmetic<D>::value),
"SineFunction not arithmetic T");
STATIC_ASSERT((std::is_arithmetic<R>::value),
"SineFunction not to arithmetic");
protected:
/// The frequency of the sine wave
const D Frequency;
/// The Ampiltude of the sine wave
const D Amplitude;
/// The Phase-shift of the sine wave
const D Phase;
/// The y-shift of the sine wave
const D Average;
public:
/// Creates an instance.
///
/// \param Frequency the frequency of the sine wave
/// \param Amplitude the amplitude of the sine wave
/// \param Phase the phase of the sine wave
/// \param Average the average of the sine wave
SineFunction(D Frequency, D Amplitude, D Phase, D Average) noexcept
: Abstraction<D, R>(Average), Frequency(Frequency), Amplitude(Amplitude),
Phase(Phase), Average(Average) {}
/// Destroys \p this object.
~SineFunction(void) = default;
/// Checks wether the Abstraction evaluates to default at the given position
/// As SineFunctions can be evaluated everythwere, this is always false
///
/// \param V the value at which to check if the function falls back to it's
/// default value.
///
/// \return false
bool isDefaultAt(const D &V) const noexcept override {
(void)V;
return false;
}
/// Evaluates the sine function
///
/// \param X the value at which to evaluate the function
/// \return the value of the sine-function at X
virtual R operator()(const D &X) const noexcept override {
return Amplitude * sin(Frequency * X + Phase) + Average;
}
};
/// Implements \c rosa::agent::Abstraction as a partial function from a domain
-// /to a range.
+/// to a range.
///
/// \note This implementation is supposed to be used to represent a partial
/// function from an arithmetic domain to an arithmetic range. This is enforced
/// statically.
///
/// A partial function is defined as a list of abstractions, where each
/// abstraction is associated a range in which it is defined. These ranges must
/// be mutually exclusive.
///
/// \tparam D type of the functions domain
/// \tparam R type of the functions range
template <typename D, typename R>
class PartialFunction : public Abstraction<D, R> {
// Make sure the actual type arguments are matching our expectations.
STATIC_ASSERT((std::is_arithmetic<D>::value), "abstracting not arithmetic");
STATIC_ASSERT((std::is_arithmetic<R>::value),
"abstracting not to arithmetic");
private:
/// A \c rosa::agent::RangeAbstraction RA is used to represent the association
/// from ranges to Abstractions.
/// This returns the Abstraction that is defined for any given value, or
/// a default Abstraction if no Abstraction is defined for that value.
RangeAbstraction<D, std::shared_ptr<Abstraction<D, R>>> RA;
public:
/// Creates an instance by Initializing the underlying \c Abstraction.
///
/// \param Map the mapping to do abstraction according to
/// \param Default abstraction to abstract to by default
///
/// \pre Each key defines a valid range such that `first <= second` and
/// there are no overlapping ranges defined by the keys.
PartialFunction(
const std::map<std::pair<D, D>, std::shared_ptr<Abstraction<D, R>>> &Map,
const R Default)
: Abstraction<D, R>(Default),
RA(Map,
std::shared_ptr<Abstraction<D, R>>(new Abstraction<D, R>(Default))) {
}
/// Destroys \p this object.
~PartialFunction(void) = default;
/// Checks wether the Abstraction evaluates to default at the given position
///
/// \param V the value at which to check if the function falls back to it's
/// default value.
///
/// \return false if the value falls into a defined range and the Abstraction
/// defined for that range does not fall back to it's default value.
bool isDefaultAt(const D &V) const noexcept override {
return RA.isDefaultAt(V) ? true : RA(V)->isDefaultAt(V);
}
/// Searches for an Abstraction for the given value and executes it for that
/// value, if such an Abstraction is found. The default Abstraction is
/// evaluated otherwise.
///
/// \param V value to abstract
///
/// \return the abstracted value based on the set mapping
R operator()(const D &V) const noexcept override {
return RA(V)->operator()(V);
}
};
} // End namespace agent
} // End namespace rosa
#endif // ROSA_AGENT_FUNCTIONABSTRACTIONS_HPP
diff --git a/include/rosa/agent/State.hpp b/include/rosa/agent/State.hpp
index 04b8584..99365de 100644
--- a/include/rosa/agent/State.hpp
+++ b/include/rosa/agent/State.hpp
@@ -1,128 +1,165 @@
//===-- 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/FunctionAbstractions.hpp"
#include "rosa/agent/Functionality.h"
#include "rosa/agent/History.hpp"
namespace rosa {
namespace agent {
-// QUESTION: I think a global variable is not fine, I think it would be better
-// to have that in private in the class. However, I have no idea how to
-// initialize it then.
-static unsigned int StateIdCounter = 0;
+// QUESTION: I would like to define the variable nextID as static variable
+// inside the struct or the class but it is not possible because I cannot define
+// it there (initialize it with 0) because "no const variable". However, using a
+// global variable is not that nice in my opinion.
+unsigned int nextID = 0;
+
+/// State conditions defining how the condition of a \c rosa::agent::State is
+/// saved in \c rosa::agent::StateInformation.
+enum class StateCondition {
+ STABLE, ///< The state is STABLE
+ DRIFTING ///< The state is drifting
+};
+
+template <typename CONFTYPE> struct StateInformation {
+ // Make sure the actual type arguments are matching our expectations.
+ STATIC_ASSERT((std::is_arithmetic<CONFTYPE>::value),
+ "confidence type is not to arithmetic");
+
+ /// The state ID saved as an unsigned integer number
+ unsigned int StateID;
+ /// The StateConfidence shows the overall confidence value of the state.
+ CONFTYPE StateConfidence;
+ /// The StateCondition shows the condition of a state (stable or drifting)
+ StateCondition StateCondition;
+ /// The StateIsValid shows whether a state is valid or invalid. In this
+ /// context, valid means that enough samples which are in close proximitry
+ /// have been inserted into the state.
+ bool StateIsValid;
+ /// The StateIsValidAfterReentrance shows whether a state is valid after the
+ /// variable changed back to it again.
+ bool StateIsValidAfterReentrance;
+};
+
+// TODO (1/2): change name of DABSTORETYPE to something else
/// \tparam INDATATYPE type of input data, \tparam DABSTORETYPE type of data
/// in which DABs are saved,
template <typename INDATATYPE, typename DABSTORETYPE>
class State : public Functionality {
// Make sure the actual type arguments are matching our expectations.
STATIC_ASSERT((std::is_arithmetic<INDATATYPE>::value),
"input data type not arithmetic");
STATIC_ASSERT((std::is_arithmetic<DABSTORETYPE>::value),
"DAB storage type is not to arithmetic");
private:
- using PartFuncPointer =
+ using partFuncPointer =
std::shared_ptr<PartialFunction<INDATATYPE, DABSTORETYPE>>;
- unsigned int StateId;
+ // TODO (2/2): because here, DABSTORETYPE makes no sense
+ StateInformation<DABSTORETYPE> StateInfo;
+
+ partFuncPointer PartialFunctionSampleMatches;
+ partFuncPointer PartialFunctionSampleMismatches;
+ partFuncPointer PartialFunctionNumOfSamplesMatches;
+ partFuncPointer PartialFunctionNumOfSamplesMismatches;
DynamicLengthHistory<INDATATYPE, HistoryPolicy::FIFO> SampleHistory;
DynamicLengthHistory<INDATATYPE, HistoryPolicy::SRWF> DAB;
DynamicLengthHistory<DABSTORETYPE, HistoryPolicy::LIFO> DABHistory;
- PartFuncPointer PartialFunctionSampleMatches;
- PartFuncPointer PartialFunctionSampleMismatches;
- PartFuncPointer PartialFunctionNumOfSamplesMatches;
- PartFuncPointer PartialFunctionNumOfSamplesMismatches;
-
+ /// The StateIsValid shows whether a state is valid or invalid. In this
+ /// context, valid means that enough samples which are in close proximitry
+ /// have been inserted into the state.
bool StateIsValid;
+ /// The StateIsValidAfterReentrance shows whether a state is valid after the
+ /// variable changed back to it again.
bool StateIsValidAfterReentrance;
public:
- State(unsigned int sampleHistorySize, unsigned int DABSize,
- unsigned int DABHistorySize,
- PartFuncPointer PartialFunctionSampleMatches,
- PartFuncPointer PartialFunctionSampleMismatches,
- PartFuncPointer PartialFunctionNumOfSamplesMatches,
- PartFuncPointer PartialFunctionNumOfSamplesMismatches) noexcept
+ State(partFuncPointer PartialFunctionSampleMatches,
+ partFuncPointer PartialFunctionSampleMismatches,
+ partFuncPointer PartialFunctionNumOfSamplesMatches,
+ partFuncPointer PartialFunctionNumOfSamplesMismatches,
+ unsigned int sampleHistorySize, unsigned int DABSize,
+ unsigned int DABHistorySize) noexcept
: SampleHistory(sampleHistorySize), DAB(DABSize),
DABHistory(DABHistorySize),
PartialFunctionSampleMatches(PartialFunctionSampleMatches),
PartialFunctionSampleMismatches(PartialFunctionSampleMismatches),
PartialFunctionNumOfSamplesMatches(PartialFunctionNumOfSamplesMatches),
PartialFunctionNumOfSamplesMismatches(
PartialFunctionNumOfSamplesMismatches) {
/*
StateIsValid = false;
StateIsValidAfterReentrance = false;
*/
}
+ /// Destroys \p this object.
~State(void) = default;
void leaveState(void) {
DAB.clear();
StateIsValidAfterReentrance = false;
}
bool insertSample(INDATATYPE Sample) {
bool workedForAll; // maybe ignor that //auc hnicht abchecken einfach kübeln
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 (DAB.full()) {
DABSTORETYPE AvgOfDAB = DAB.average<DABSTORETYPE>();
workedForAll &= DABHistory.addEntry(AvgOfDAB);
if (workedForAll) {
DAB.clear();
} // QUESTION: - what should be done if it has not worked?
}
if (workedForAll) {
// TODO: calculate whether state is valid
}
}
}
return workedForAll;
}
- // DDAB confSampleMatchesState(DIN sample) { return NULL; }
+ DABSTORETYPE confSampleMatchesState(INDATATYPE sample) {}
- // DDAB confSampleMismatchesState() {}
+ DABSTORETYPE confSampleMismatchesState(INDATATYPE sample) {}
- unsigned int stateId(void) { return StateId; }
+ // unsigned int stateId(void) { return StateId; }
};
} // End namespace agent
} // End namespace rosa
#endif // ROSA_AGENT_STATE_HPP
diff --git a/include/rosa/agent/StateDetector.hpp b/include/rosa/agent/StateDetector.hpp
index fc1ee37..18486d5 100644
--- a/include/rosa/agent/StateDetector.hpp
+++ b/include/rosa/agent/StateDetector.hpp
@@ -1,208 +1,226 @@
//===-- 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/FunctionAbstractions.hpp"
#include "rosa/agent/Functionality.h"
#include "rosa/agent/State.hpp"
-#include <memory>
#include <vector>
namespace rosa {
namespace agent {
-template <typename CONFTYPE> struct StateInformation {
- unsigned int statenumber;
- CONFTYPE confidences;
- bool stable; // maybe: conf
- bool drift; // maybe: conf
- bool stateUnchanged; // check name
-};
-
-// DIN = Input Datatype, CONF = Confidence Datatype
+/// Implements \c rosa::agent::StateDetector as a functionality that detects
+/// states given on input samples.
+///
+/// \note This implementation is supposed to be used for samples of an
+/// arithmetic type.
+///
/// \tparam INDATATYPE is the type of input data, \tparam CONFTYPE is type of
/// data in that the confidence values are given
template <typename INDATATYPE, typename CONFTYPE>
class StateDetector : public Functionality {
// Make sure the actual type arguments are matching our expectations.
STATIC_ASSERT((std::is_arithmetic<INDATATYPE>::value),
"input data type not arithmetic");
STATIC_ASSERT((std::is_arithmetic<CONFTYPE>::value),
"confidence abstraction type is not to arithmetic");
private:
+ // For the convinience to write a shorter data type name
using partFuncPointer =
std::shared_ptr<PartialFunction<INDATATYPE, CONFTYPE>>;
using statePtr = std::shared_ptr<StateInformation<CONFTYPE>>;
+ using stateInfoPtr = std::shared_ptr<StateInformation<CONFTYPE>>;
- unsigned int discreteAveragePartitionCounter;
+ /// The StateHasChanged is a flag that show whether a state change has
+ /// happened.
+ bool StateHasChanged;
- std::shared_ptr<statePtr> ActualState;
+ /// The CurrentState is a pointer to the (saved) state in which the actual
+ /// variable (signal) of the observed system is.
+ std::shared_ptr<statePtr> CurrentState;
+ /// The DetectedStates is vector in that all detected states are saved.
std::vector<statePtr> DetectedStates;
- bool stateIsValid;
- bool stateIsValidAfterReentrance;
-
+ /// The PartialFunctionSampleMatches is the fuzzy function that gives the
+ /// convidence how good the new sample matches another sample in the sample
+ /// history.
partFuncPointer PartialFunctionSampleMatches;
+ /// The PartialFunctionSampleMatches is the fuzzy function that gives the
+ /// convidence how bad the new sample matches another sample in the sample
+ /// history.
partFuncPointer PartialFunctionSampleMismatches;
+ /// The PartialFunctionSampleMatches is the fuzzy function that gives the
+ /// convidence how many samples from the sampe history match the new sample.
partFuncPointer PartialFunctionNumOfSamplesMatches;
+ /// The PartialFunctionSampleMatches is the fuzzy function that gives the
+ /// convidence how many samples from the sampe history mismatch the new
+ /// sample.
partFuncPointer PartialFunctionNumOfSamplesMismatches;
+ /// SampleHistorySize is the (maximum) size of the sample history.
unsigned int SampleHistorySize;
+ /// DABSize the size of a DAB (Discrete Average Block).
unsigned int DABSize;
+ /// DABHistorySize is the (maximum) size of the DAB history.
unsigned int DABHistorySize;
- //@Benedikt: partialfunction/linearfunction: steigung/domain ändern
- //@Benedikt: linearfunction set k,d or x1/y1 and x2/y2
-
- // QUESTION: Do we need the following to flag
- bool StateHasChanged;
-
public:
- // TODO: finish constructor
- StateDetector() noexcept {
-
- ActualState = NULL; // MAYBE CHANGE TO CURRENT oder Active
- }
-
- /// A sample is input of the function, state detector is looking for a
- /// matching state. If it finds a matching one, it inserts the sample,
- /// otherwiese it creates a new state.
- std::shared_ptr<StateInformation<CONFTYPE>>
- detectState(INDATATYPE Sample) { // return tuple oder struct (statenumber,
- // confidences, stable, drift, changed/unchanged)
-
- std::shared_ptr<StateInformation<CONFTYPE>> StateInfo;
-
- if (ActualState == NULL) {
+ /// Creates an instance by setting all parameters
+ StateDetector(partFuncPointer PartialFunctionSampleMatches,
+ partFuncPointer PartialFunctionSampleMismatches,
+ partFuncPointer PartialFunctionNumOfSamplesMatches,
+ partFuncPointer PartialFunctionNumOfSamplesMismatches,
+ unsigned int SampleHistorySize, unsigned int DABSize,
+ unsigned int DABHistorySize) noexcept
+ : StateHasChanged(false), CurrentState(NULL),
+ PartialFunctionSampleMatches(PartialFunctionSampleMatches),
+ PartialFunctionSampleMismatches(PartialFunctionSampleMismatches),
+ PartialFunctionNumOfSamplesMatches(PartialFunctionNumOfSamplesMatches),
+ PartialFunctionNumOfSamplesMismatches(
+ PartialFunctionNumOfSamplesMismatches),
+ SampleHistorySize(SampleHistorySize), DABSize(DABSize),
+ DABHistorySize(DABHistorySize) {}
+
+ /// Destroys \p this object.
+ ~StateDetector(void) = default;
+
+ /// Detects the state to which the new sample belongs or create a new state if
+ /// the new sample does not match to any of the saved states.
+ ///
+ /// \param Sample
+ ///
+ /// \return the information of the actual state (state ID and other
+ /// parameters)
+ stateInfoPtr detectState(INDATATYPE Sample) {
+
+ if (CurrentState == NULL) {
ASSERT(DetectedStates.empty());
- if (statePtr S = createNewState()) {
-
- ActualState = S;
-
- } // QUESTION: should there an output (log) when it was not successfull?
+ statePtr S = createNewState();
+ if (S) {
+ CurrentState = S;
+ } else {
+ // TODO: handle (or at least log) if now state could be created
+ }
} else {
CONFTYPE ConfidenceSampleMatchesState =
- ActualState->confSampleMatchesState(Sample);
+ CurrentState->confSampleMatchesState(Sample);
CONFTYPE ConfidenceSampleMismatchesState =
- ActualState->confSampleMismatchesState(Sample);
+ CurrentState->confSampleMismatchesState(Sample);
if (ConfidenceSampleMatchesState > ConfidenceSampleMismatchesState) {
-
StateHasChanged = false;
-
} else {
-
StateHasChanged = true;
// TODO: check whether ActiveState is valid
+
// TODO: if invalid -> deleteState (einfach pop weil shared pointer)
+ // a.erase(std::find(a.begin(),a.end(),2));
// TODO: else leaveState
// TODO FAR AWAY FUTURE: additionally save averages to enable fast
// iteration through recorded state vector
//- maybe sort vector based on these average values
- ActualState = NULL;
+ CurrentState = NULL;
+
for (auto &SavedState : DetectedStates) {
- if (SavedState != ActualState) {
+ if (SavedState != CurrentState) {
CONFTYPE ConfidenceSampleMatchesState =
SavedState->confSampleMatchesState(Sample);
CONFTYPE ConfidenceSampleMismatchesState =
SavedState->confSampleMismatchesState(Sample);
if (ConfidenceSampleMatchesState >
ConfidenceSampleMismatchesState) {
// QUESTION: maybe it would be better to compare
// ConfidenceSampleMatchesState
// of all states in the vector
- ActualState = SavedState;
+ CurrentState = SavedState;
break;
}
}
}
- if (!ActualState) {
+ if (!CurrentState) {
if (statePtr S = createNewState()) {
- ActualState = S;
+ CurrentState = S;
} // QUESTION: should there an output (log) when it was not
// successfull?
}
}
}
- ActualState->insertSample(Sample);
+ CurrentState->insertSample(Sample);
// TODO: check actual state whether it drifts
// TODO: write in StateInfo
- return StateInfo;
+ return CurrentState->stateInfo();
}
bool stateHasChanged(void) { return StateHasChanged; }
bool stateIsUnchanged(void) { return !StateHasChanged; }
// TODO: get confidences, get drift/stable get, get active state number,
// TODO: maybe just return struct with everything
private:
- statePtr createNewState() {
-
- bool CreatingWorked;
+ /// Creates a new state and adds this state to the state vector in which all
+ /// known states are saved.
+ ///
+ /// \param SampleHistorySize the (maximum) size of the sample history.
+ /// \param DABSize the size of a DAB.
+ /// \param DABHistorySize the (maximum) size of the DAB history.
+ /// \param PartialFunctionSampleMatches the
+ /// \param PartialFunctionSampleMismatches
+ /// \param PartialFunctionNumOfSamplesMatches
+ /// \param PartialFunctionNumOfSamplesMismatches
+ ///
+ /// \return the new created state or NULL if no state could be created.
+ statePtr createNewState(void) {
statePtr S = new (std::nothrow)
- State(StateIdCounter, SampleHistorySize, DABSize, DABHistorySize,
+ State(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++;
-
+ DetectedStates.push_back(S);
return S;
} else {
return NULL;
}
}
};
} // End namespace agent
} // End namespace rosa
#endif // ROSA_AGENT_STATEDETECTOR_HPP

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jul 3, 10:24 PM (15 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
157377
Default Alt Text
(25 KB)

Event Timeline