diff --git a/examples/agent-functionalities/agent-functionalities.cpp b/examples/agent-functionalities/agent-functionalities.cpp index 8ad2288..2da67b8 100644 --- a/examples/agent-functionalities/agent-functionalities.cpp +++ b/examples/agent-functionalities/agent-functionalities.cpp @@ -1,169 +1,170 @@ //===-- examples/agent-functionalities/agent-functionalities.cpp *-- C++-*-===// // // The RoSA Framework // //===----------------------------------------------------------------------===// /// /// \file examples/agent-functionalities/agent-functionalities.cpp /// /// \author David Juhasz (david.juhasz@tuwien.ac.at) /// /// \date 2017 /// /// \brief A simple example on defining \c rosa::Agent instances using /// \c rosa::agent::Functionality object as components. /// //===----------------------------------------------------------------------===// #include "rosa/agent/Abstraction.hpp" -#include "rosa/agent/LinearFunctions.hpp" +#include "rosa/agent/FunctionAbstractions.hpp" +#include "rosa/agent/RangeConfidence.hpp" #include "rosa/agent/Confidence.hpp" #include "rosa/config/version.h" #include "rosa/core/Agent.hpp" #include "rosa/core/MessagingSystem.hpp" #include "rosa/support/log.h" #include "rosa/support/terminal_colors.h" #include using namespace rosa; using namespace rosa::agent; using namespace rosa::terminal; /// A dummy wrapper for testing \c rosa::MessagingSystem. /// /// \note Since we test \c rosa::MessagingSystem directly here, we need to get /// access to its protected members. That we do by imitating to be a decent /// subclass of \c rosa::MessagingSystem, while calling protected member /// functions on an object of a type from which we actually don't inherit. struct SystemTester : protected MessagingSystem { template static AgentHandle createMyAgent(MessagingSystem *S, const std::string &Name, Funs &&... Fs) { return ((SystemTester *)S)->createAgent(Name, std::move(Fs)...); } static void destroyMyAgent(MessagingSystem *S, const AgentHandle &H) { ((SystemTester *)S)->destroyUnit(unwrapAgent(H)); } }; /// A special \c rosa::Agent with its own state. class MyAgent : public Agent { public: using Tick = AtomConstant; private: enum class Categories { Bad, Normal, Good }; static const std::map CategoryNames; History H; Confidence C; RangeAbstraction A; PartialFunction L; RangeConfidence RCL; RangeConfidence RCS; public: void handler(Tick, uint8_t V) noexcept { // Record \p V to the \c rosa::agent::History, then print state info. H << V; ASSERT(H.entry() == V); // Sanity check. LOG_INFO_STREAM << "\nNext value: " << PRINTABLE(V) << ", confidence: " << C(H) << ", category: " << CategoryNames.at(A(H.entry())) << ", partial: " << int(L(H.entry())) << ", range-confidence-linear: "; std::vector res_lin = RCL(H.entry()); for (auto i : res_lin){ LOG_INFO_STREAM << " " << i; } LOG_INFO_STREAM << ", range-confidence-sine: "; std::vector res_sine = RCS(H.entry()); for (auto i : res_sine){ LOG_INFO_STREAM << " " << i; } LOG_INFO_STREAM << '\n'; } MyAgent(const AtomValue Kind, const rosa::id_t Id, const std::string &Name, MessagingSystem &S) : Agent(Kind, Id, Name, S, THISMEMBER(handler)), H(), C(5, 20, 1), A({{{(uint8_t)10, (uint8_t)14}, Categories::Normal}, {{(uint8_t)15, (uint8_t)17}, Categories::Good}, {{(uint8_t)18, (uint8_t)19}, Categories::Normal}}, Categories::Bad), L({{{0, 2}, std::make_shared>(0, 1)}, {{2, 4}, std::make_shared>(2, 0)}, {{4, 6}, std::make_shared>(6, -1)}}, 0), RCL({ PartialFunction({ {{0, 3}, std::make_shared>(0, 1.0/3)}, {{3, 6}, std::make_shared>(1, 0)}, {{6, 9}, std::make_shared>(3.0, -1.0/3)}, },0), PartialFunction({ {{6, 9}, std::make_shared>(-2, 1.0/3)}, {{9, 12}, std::make_shared>(1, 0)}, {{12, 15}, std::make_shared>(5, -1.0/3)}, },0), PartialFunction({ {{12, 15}, std::make_shared>(-4, 1.0/3)}, {{15, 18}, std::make_shared>(1, 0)}, {{18, 21}, std::make_shared>(7, -1.0/3)}, },0) }), RCS({ PartialFunction({ {{0, 3}, std::make_shared> (M_PI/3, 0.5, -M_PI/2, 0.5)}, {{3, 6}, std::make_shared>(1, 0)}, {{6, 9}, std::make_shared> (M_PI/3, 0.5, -M_PI/2 + 3, 0.5)}, },0), PartialFunction({ {{6, 9}, std::make_shared> (M_PI/3, 0.5, -M_PI/2, 0.5)}, {{9, 12}, std::make_shared>(1, 0)}, {{12, 15}, std::make_shared> (M_PI/3, 0.5, -M_PI/2 + 3, 0.5)}, },0), PartialFunction({ {{12, 15}, std::make_shared> (M_PI/3, 0.5, -M_PI/2, 0.5)}, {{15, 18}, std::make_shared>(1, 0)}, {{18, 21}, std::make_shared> (M_PI/3, 0.5, -M_PI/2 + 3, 0.5)}, },0) }){} }; const std::map MyAgent::CategoryNames{ {Categories::Bad, "Bad"}, {Categories::Normal, "Normal"}, {Categories::Good, "Good"}}; int main(void) { LOG_INFO_STREAM << library_string() << " -- " << Color::Red << "agent-functionalities example" << Color::Default << '\n'; std::unique_ptr S = MessagingSystem::createSystem("Sys"); MessagingSystem *SP = S.get(); AgentHandle A = SystemTester::createMyAgent(SP, "MyAgent"); std::vector Vs{0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 13, 15, 14, 15, 16, 19, 20, 21}; for (auto I = Vs.begin(); I != Vs.end(); ++I) { A.send(MyAgent::Tick::Value, *I); } SystemTester::destroyMyAgent(SP, A); return 0; } diff --git a/include/rosa/agent/LinearFunctions.hpp b/include/rosa/agent/FunctionAbstractions.hpp similarity index 70% rename from include/rosa/agent/LinearFunctions.hpp rename to include/rosa/agent/FunctionAbstractions.hpp index 56e425d..1cd0d10 100644 --- a/include/rosa/agent/LinearFunctions.hpp +++ b/include/rosa/agent/FunctionAbstractions.hpp @@ -1,228 +1,175 @@ -//===-- rosa/agent/LinearAbstractions.hpp --------------------------*- C++ -*-===// +//===-- rosa/agent/FunctionAbstractions.hpp ---------------------*- C++ -*-===// // // The RoSA Framework // //===----------------------------------------------------------------------===// /// -/// \file rosa/agent/LinearAbstractions.hpp +/// \file rosa/agent/FunctionAbstractions.hpp /// /// \author Benedikt Tutzer (benedikt.tutzer@tuwien.ac.at) /// /// \date 2019 /// -/// \brief Definition of *LinearFunction* *functionality*. +/// \brief Definition of *FunctionAbstractions* *functionality*. /// //===----------------------------------------------------------------------===// -#ifndef ROSA_AGENT_LINEARFUNCTIONS_HPP -#define ROSA_AGENT_LINEARFUNCTIONS_HPP +#ifndef ROSA_AGENT_FUNCTIONABSTRACTIONS_HPP +#define ROSA_AGENT_FUNCTIONABSTRACTIONS_HPP #include "rosa/agent/Functionality.h" #include "rosa/agent/Abstraction.hpp" #include "rosa/support/debug.hpp" #include #include #include #include namespace rosa { namespace agent { /// Evaluates a linear function at a given value. /// /// \tparam T type of the functions domain /// \tparam A type of the functions range template class LinearFunction : public Abstraction{ // Make sure the actual type arguments are matching our expectations. STATIC_ASSERT((std::is_arithmetic::value), "LinearFunction not arithmetic T"); STATIC_ASSERT((std::is_arithmetic::value), "LinearFunction not to arithmetic"); protected: const T Intercept; const T Coefficient; public: /// Creates an instance. /// /// \param Intercept the intercept of the linear function /// \param Coefficient the coefficient of the linear function /// domain LinearFunction(T Intercept, T Coefficient) noexcept : Abstraction(Intercept), Intercept(Intercept), Coefficient(Coefficient) {} /// Destroys \p this object. ~LinearFunction(void) = default; /// Evaluates the linear function /// /// \param X the value at which to evaluate the function /// \return the result virtual A operator()(const T &X) const noexcept override { return Intercept + X*Coefficient; } }; /// Evaluates a sine function at a given value. /// /// \tparam T type of the functions domain /// \tparam A type of the functions range template class SineFunction : public Abstraction{ // Make sure the actual type arguments are matching our expectations. STATIC_ASSERT((std::is_arithmetic::value), "SineFunction not arithmetic T"); STATIC_ASSERT((std::is_arithmetic::value), "SineFunction not to arithmetic"); protected: const T Frequency; const T Amplitude; const T Phase; const T 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 /// domain SineFunction(T Frequency, T Amplitude, T Phase, T Average) noexcept : Abstraction(Average), Frequency(Frequency), Amplitude(Amplitude), Phase(Phase), Average(Average) {} /// Destroys \p this object. ~SineFunction(void) = default; /// Evaluates the linear function /// /// \param X the value at which to evaluate the function /// \return the result virtual A operator()(const T &X) const noexcept override { return Amplitude*sin(Frequency * X + Phase) + Average; } }; /// Implements \c rosa::agent::RangeAbstraction as an abstraction from /// \c std::map from ranges of a type to abstractions of that type to another /// type. The resulting abstractions are evaluated for the given values. /// /// \note This implementation is supposed to be used to abstract ranges of /// arithmetic types into abstractions from that type to another arithmetic /// type, which is statically enforced. /// /// \invariant The keys in the underlying \c std::map define valid ranges /// such that `first <= second` and there are no overlapping ranges defined by /// the keys. /// /// \tparam T type to abstract from /// \tparam A type to abstract to template class PartialFunction : private Abstraction { // Make sure the actual type arguments are matching our expectations. STATIC_ASSERT((std::is_arithmetic::value), "abstracting not arithmetic"); STATIC_ASSERT((std::is_arithmetic::value), "abstracting not to arithmetic"); private: RangeAbstraction>> RA; public: /// Creates an instance by Initializing the underlying \c RangeAbstraction. /// /// \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::shared_ptr>> &Map, const A Default) : Abstraction(Default), RA(Map, std::shared_ptr> (new Abstraction(Default))) { } /// Destroys \p this object. ~PartialFunction(void) = default; /// Evaluates an Abstraction from type \p T to type \p A based on the set /// mapping. /// /// Results in the value associated by the set mapping to the argument, or /// \c rosa::agent::RangeAbstraction::Default if the actual argument is not /// included in any of the ranges in the set mapping. /// /// \param V value to abstract /// /// \return the abstracted value based on the set mapping A operator()(const T &V) const noexcept override { return RA(V)->operator()(V); } }; - -/// Evaluates a vector of Abstractions at a given value and returns the results -/// as a vector -/// -/// \note This implementation is supposed to be used to abstract ranges of -/// arithmetic types into vectors of another arithmetic type, which is -/// statically enforced. -/// -/// \tparam T type to abstract from -/// \tparam A type to abstract a vector of to -template -class RangeConfidence : public Abstraction>, - private std::vector>{ - // Make sure the actual type arguments are matching our expectations. - STATIC_ASSERT((std::is_arithmetic::value), "abstracting not arithmetic"); - STATIC_ASSERT((std::is_arithmetic::value), - "abstracting not to arithmetic"); - - // Bringing into scope inherited members. - using std::vector>::size; - using std::vector>::begin; - using std::vector>::end; - -public: - /// Creates an instance by Initializing the underlying \c RangeAbstraction. - /// - /// \param Abstractions the Abstractions to be evaluated - RangeConfidence(const std::vector> &Abstractions) - : Abstraction>({}), - std::vector>(Abstractions) { - } - - /// Destroys \p this object. - ~RangeConfidence(void) = default; - - /// Evaluates an Abstraction from type \p T to type \p A based on the set - /// mapping. - /// - /// Results in the value associated by the set mapping to the argument, or - /// \c rosa::agent::RangeAbstraction::Default if the actual argument is not - /// included in any of the ranges in the set mapping. - /// - /// \param V value to abstract - /// - /// \return the abstracted value based on the set mapping - std::vector operator()(const T &V) const noexcept override { - std::vector ret; - for (auto const& func : ((std::vector>)*this)){ - ret.push_back(func(V)); - } - return ret; - } -}; } // End namespace agent } // End namespace rosa -#endif // ROSA_AGENT_ABSTRACTION_HPP +#endif // ROSA_AGENT_FUNCTIONABSTRACTIONS_HPP diff --git a/include/rosa/agent/RangeConfidence.hpp b/include/rosa/agent/RangeConfidence.hpp new file mode 100644 index 0000000..0966a87 --- /dev/null +++ b/include/rosa/agent/RangeConfidence.hpp @@ -0,0 +1,89 @@ +//===-- rosa/agent/RangeConfidence.hpp --------------------------*- C++ -*-===// +// +// The RoSA Framework +// +//===----------------------------------------------------------------------===// +/// +/// \file rosa/agent/RangeConfidence.hpp +/// +/// \author Benedikt Tutzer (benedikt.tutzer@tuwien.ac.at) +/// +/// \date 2019 +/// +/// \brief Definition of *RangeConfidence* *functionality*. +/// +//===----------------------------------------------------------------------===// + +#ifndef ROSA_AGENT_RANGECONFIDENCE_HPP +#define ROSA_AGENT_RANGECONFIDENCE_HPP + +#include "rosa/agent/Functionality.h" +#include "rosa/agent/Abstraction.hpp" +#include "rosa/agent/FunctionAbstractions.hpp" + +#include "rosa/support/debug.hpp" + +#include +#include +#include +#include + +namespace rosa { +namespace agent { + +/// Evaluates a vector of Abstractions at a given value and returns the results +/// as a vector +/// +/// \note This implementation is supposed to be used to abstract ranges of +/// arithmetic types into vectors of another arithmetic type, which is +/// statically enforced. +/// +/// \tparam T type to abstract from +/// \tparam A type to abstract a vector of to +template +class RangeConfidence : public Abstraction>, + private std::vector>{ + // Make sure the actual type arguments are matching our expectations. + STATIC_ASSERT((std::is_arithmetic::value), "abstracting not arithmetic"); + STATIC_ASSERT((std::is_arithmetic::value), + "abstracting not to arithmetic"); + + // Bringing into scope inherited members. + using std::vector>::size; + using std::vector>::begin; + using std::vector>::end; + +public: + /// Creates an instance by Initializing the underlying \c RangeAbstraction. + /// + /// \param Abstractions the Abstractions to be evaluated + RangeConfidence(const std::vector> &Abstractions) + : Abstraction>({}), + std::vector>(Abstractions) { + } + + /// Destroys \p this object. + ~RangeConfidence(void) = default; + + /// Evaluates an Abstraction from type \p T to type \p A based on the set + /// mapping. + /// + /// Results in the value associated by the set mapping to the argument, or + /// \c rosa::agent::RangeAbstraction::Default if the actual argument is not + /// included in any of the ranges in the set mapping. + /// + /// \param V value to abstract + /// + /// \return the abstracted value based on the set mapping + std::vector operator()(const T &V) const noexcept override { + std::vector ret; + for (auto const& func : ((std::vector>)*this)){ + ret.push_back(func(V)); + } + return ret; + } +}; +} // End namespace agent +} // End namespace rosa + +#endif // ROSA_AGENT_RANGECONFIDENCE_HPP diff --git a/lib/agent/CMakeLists.txt b/lib/agent/CMakeLists.txt index 3d6e5ab..7edb556 100644 --- a/lib/agent/CMakeLists.txt +++ b/lib/agent/CMakeLists.txt @@ -1,16 +1,18 @@ set(LIB_INCLUDE_DIR ${ROSA_MAIN_INCLUDE_DIR}/rosa/agent) add_library(ROSAAgent ${LIB_INCLUDE_DIR}/namespace.h namespace.cpp ${LIB_INCLUDE_DIR}/Functionality.h Functionality.cpp ${LIB_INCLUDE_DIR}/Abstraction.hpp Abstraction.cpp - ${LIB_INCLUDE_DIR}/LinearFunctions.hpp - LinearFunctions.cpp + ${LIB_INCLUDE_DIR}/FunctionAbstractions.hpp + FunctionAbstractions.cpp + ${LIB_INCLUDE_DIR}/RangeConfidence.hpp + RangeConfidence.cpp ${LIB_INCLUDE_DIR}/History.hpp History.cpp ${LIB_INCLUDE_DIR}/Confidence.hpp Confidence.cpp ) diff --git a/lib/agent/LinearFunctions.cpp b/lib/agent/FunctionAbstractions.cpp similarity index 60% copy from lib/agent/LinearFunctions.cpp copy to lib/agent/FunctionAbstractions.cpp index 0b43abe..0206760 100644 --- a/lib/agent/LinearFunctions.cpp +++ b/lib/agent/FunctionAbstractions.cpp @@ -1,20 +1,20 @@ -//===-- agent/LinearFunctions.cpp -------------------------------*- C++ -*-===// +//===-- agent/FunctionAbstractions.cpp --------------------------*- C++ -*-===// // // The RoSA Framework // //===----------------------------------------------------------------------===// /// -/// \file agent/LinearFunctions.cpp +/// \file agent/FunctionAbstractions.cpp /// /// \author Benedikt Tutzer (benedikt.tutzer@tuwien.ac.at) /// /// \date 2019 /// -/// \brief Implementation for rosa/agent/LinearFunctions.hpp. +/// \brief Implementation for rosa/agent/FunctionAbstractions.hpp. /// /// \note Empty implementation, source file here to have a compile database -/// entry for rosa/agent/LinearFunctions.hpp. +/// entry for rosa/agent/FunctionAbstractions.hpp. /// //===----------------------------------------------------------------------===// -#include "rosa/agent/LinearFunctions.hpp" +#include "rosa/agent/FunctionAbstractions.hpp" diff --git a/lib/agent/LinearFunctions.cpp b/lib/agent/RangeConfidence.cpp similarity index 61% rename from lib/agent/LinearFunctions.cpp rename to lib/agent/RangeConfidence.cpp index 0b43abe..415f11f 100644 --- a/lib/agent/LinearFunctions.cpp +++ b/lib/agent/RangeConfidence.cpp @@ -1,20 +1,20 @@ -//===-- agent/LinearFunctions.cpp -------------------------------*- C++ -*-===// +//===-- agent/RangeConfidence.cpp -------------------------------*- C++ -*-===// // // The RoSA Framework // //===----------------------------------------------------------------------===// /// -/// \file agent/LinearFunctions.cpp +/// \file agent/RangeConfidence.cpp /// /// \author Benedikt Tutzer (benedikt.tutzer@tuwien.ac.at) /// /// \date 2019 /// -/// \brief Implementation for rosa/agent/LinearFunctions.hpp. +/// \brief Implementation for rosa/agent/RangeConfidence.hpp. /// /// \note Empty implementation, source file here to have a compile database -/// entry for rosa/agent/LinearFunctions.hpp. +/// entry for rosa/agent/RangeConfidence.hpp. /// //===----------------------------------------------------------------------===// -#include "rosa/agent/LinearFunctions.hpp" +#include "rosa/agent/RangeConfidence.hpp"