diff --git a/include/rosa/agent/experimental/StateHandler.hpp b/include/rosa/agent/experimental/StateHandler.hpp new file mode 100644 index 0000000..d2ff364 --- /dev/null +++ b/include/rosa/agent/experimental/StateHandler.hpp @@ -0,0 +1,193 @@ +//===-- rosa/agent/experimental/StateHandler.hpp ----------------*- C++ -*-===// +// +// The RoSA Framework +// +//===----------------------------------------------------------------------===// +/// +/// \file rosa/agent/experimental/StateHandler.hpp +/// +/// \author Maximilian Götzinger (maxgot@utu.fi) +/// +/// \date 2017 +/// +/// \brief Definition of *experimental* *abstraction* *functionality*. +/// +//===----------------------------------------------------------------------===// + +#ifndef ROSA_AGENT_EXPERIMENTAL_STATEHANDLER_HPP +#define ROSA_AGENT_EXPERIMENTAL_STATEHANDLER_HPP + +//#include "rosa/agent/Functionality.h" + +#include "rosa/support/debug.hpp" + +#include +#include + +namespace rosa { +namespace agent { + +/* +/// Abstracts values from a type to another one. +/// +/// \tparam T type to abstract from +/// \tparam A type to abstract to +template class Abstraction : public Functionality { +protected: + /// Value to abstract to by default. + const A Default; + +public: + /// Creates an instance. + /// + /// \param Default value to abstract to by default + Abstraction(const A Default) noexcept : Default(Default) {} + + /// Destroys \p this object. + ~Abstraction(void) = default; + + /// Abstracts a value from type \p T to type \p A. + /// + /// \note The default implementation always returns + /// \c rosa::agent::Abstraction::Default, hence the actual argument is + /// ignored. + /// + /// \return the abstracted value + virtual A operator()(const T &) const noexcept { return Default; } +}; + +/// Implements \c rosa::agent::Abstraction as a \c std::map from a type to +/// another one. +/// +/// \note This implementation is supposed to be used to abstract between +/// enumeration types, which is statically enforced. +/// +/// \tparam T type to abstract from +/// \tparam A type to abstract to +template +class MapAbstraction : public Abstraction, private std::map { + // Make sure the actual type arguments are enumerations. + STATIC_ASSERT((std::is_enum::value && std::is_enum::value), + "mapping not enumerations"); + + // Bringing into scope inherited members. + using Abstraction::Default; + using std::map::end; + using std::map::find; + +public: + /// Creates an instance by initializing the underlying \c std::map. + /// + /// \param Map the mapping to do abstraction according to + /// \param Default value to abstract to by default + MapAbstraction(const std::map &Map, const A Default) noexcept + : Abstraction(Default), + std::map(Map) {} + + /// Destroys \p this object. + ~MapAbstraction(void) = default; + + /// Abstracts a value 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::MapAbstraction::Default if the actual argument is not + /// associated with anything by 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 { + const auto I = find(V); + return I == end() ? Default : *I; + } +}; + +/// Implements \c rosa::agent::Abstraction as a \c std::map from ranges of a +/// type to values of another type. +/// +/// \note This implementation is supposed to be used to abstract ranges of +/// arithmetic types into enumerations, 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 RangeAbstraction : public Abstraction, + private std::map, A> { + // Make sure the actual type arguments are matching our expectations. + STATIC_ASSERT((std::is_arithmetic::value), "abstracting not arithmetic"); + STATIC_ASSERT((std::is_enum::value), "abstracting not to enumeration"); + + // Bringing into scope inherited members. + using Abstraction::Default; + using std::map, A>::begin; + using std::map, A>::end; + using std::map, A>::find; + +public: + /// Creates an instance by Initializing the unserlying \c std::map. + /// + /// \param Map the mapping to do abstraction according to + /// \param Default value 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. + RangeAbstraction(const std::map, A> &Map, const A &Default) + : Abstraction(Default), std::map, A>(Map) { + // Sanity check. + ASSERT(std::all_of( + begin(), end(), [this](const std::pair, A> &P) { + return P.first.first <= P.first.second && + std::all_of(++find(P.first), end(), + [&P](const std::pair, A> &R) { + // \note Values in \c Map are sorted. + return P.first.first < P.first.second && + P.first.second <= R.first.first || + P.first.first == P.first.second && + P.first.second < R.first.first; + }); + })); + } + + /// Destroys \p this object. + ~RangeAbstraction(void) = default; + + /// Abstracts a value 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 { + auto I = begin(); + bool Found = false; // Indicates if \c I refers to a matching range. + bool Failed = false; // Indicates if it is pointless to continue searching. + while (!Found && !Failed && I != end()) { + if (V < I->first.first) { + // No match so far and \p V is below the next range, never will match. + // \note Keys are sorted in the map. + Failed = true; + } else if (I->first.first <= V && V < I->first.second) { + // Matching range found. + Found = true; + } else { + // Cannot conclude in this step, move to the next range. + ++I; + } + } + ASSERT(!Found || I != end()); + return Found ? I->second : Default; + } +}; +*/ + +} // End namespace agent +} // End namespace rosa + +#endif // ROSA_AGENT_EXPERIMENTAL_STATEHANDLER_HPP diff --git a/include/rosa/agent/experimental/namespace.h b/include/rosa/agent/experimental/namespace.h new file mode 100644 index 0000000..6d2b7db --- /dev/null +++ b/include/rosa/agent/experimental/namespace.h @@ -0,0 +1,34 @@ +//===-- rosa/agent/experimental/namespace.h ---------------------*- C++ -*-===// +// +// The RoSA Framework +// +//===----------------------------------------------------------------------===// +/// +/// \file rosa/agent/experimental/namespace.h +/// +/// \author Maximilian Götzinger (maxgot@utu.fi) +/// +/// \date 2017 +/// +/// \brief Documentation for namespace \c rosa::agent::experimental. +/// +//===----------------------------------------------------------------------===// + +#ifndef ROSA_AGENT_EXPERIMENTAL_NAMESPACE_H +#define ROSA_AGENT_EXPERIMENTAL_NAMESPACE_H + +namespace rosa { + +/// Contains functionalities that are supposed to be useful for implementing +/// *agents*. +namespace agent { + +/// Contains experimental functionalities that are supposed to be useful for implementing +/// *agents*. +namespace experimental {} + +} // End namespace agent + +} // End namespace rosa + +#endif // ROSA_AGENT_EXPERIMENTAL_NAMESPACE_H diff --git a/lib/agent/CMakeLists.txt b/lib/agent/CMakeLists.txt index 81a33f5..4a3d5d1 100644 --- a/lib/agent/CMakeLists.txt +++ b/lib/agent/CMakeLists.txt @@ -1,14 +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}/History.hpp History.cpp ${LIB_INCLUDE_DIR}/Confidence.hpp Confidence.cpp + ${LIB_INCLUDE_DIR}/experimental/namespace.h + experimental/namespace.cpp + ${LIB_INCLUDE_DIR}/experimental/StateHandler.hpp + experimental/StateHandler.cpp ) diff --git a/lib/agent/experimental/StateHandler.cpp b/lib/agent/experimental/StateHandler.cpp new file mode 100644 index 0000000..4a0c93e --- /dev/null +++ b/lib/agent/experimental/StateHandler.cpp @@ -0,0 +1,20 @@ +//===-- agent/experimental/StateHandler.cpp ---------------------*- C++ -*-===// +// +// The RoSA Framework +// +//===----------------------------------------------------------------------===// +/// +/// \file agent/experimental/StateHandler.cpp +/// +/// \author Maximilian Götzinger (maxgot@utu.fi) +/// +/// \date 2017 +/// +/// \brief Implementation for rosa/agent/experimental/StateHandler.h. +/// +/// \note Empty implementation, source file here to have a compile database +/// entry for rosa/agent/experimental/StateHandler.h. +/// +//===----------------------------------------------------------------------===// + +#include "rosa/agent/experimental/StateHandler.hpp" diff --git a/lib/agent/experimental/namespace.cpp b/lib/agent/experimental/namespace.cpp new file mode 100644 index 0000000..82cb4a6 --- /dev/null +++ b/lib/agent/experimental/namespace.cpp @@ -0,0 +1,20 @@ +//===-- agent/experimental/namespace.cpp ------------------------*- C++ -*-===// +// +// The RoSA Framework +// +//===----------------------------------------------------------------------===// +/// +/// \file agent/experimental/namespace.cpp +/// +/// \author Maximilian Götzinger (maxgot@utu.fi) +/// +/// \date 2017 +/// +/// \brief Implementation for rosa/agent/experimental/namespace.h. +/// +/// \note Empty implementation, source file here to have a compile database +/// entry for rosa/agent/experimental/namespace.h. +/// +//===----------------------------------------------------------------------===// + +#include "rosa/agent/experimental/namespace.h"