Commit 456fea77 authored by Lionel's avatar Lionel

Features/ranged and discritzed types

parent b41ff9c6
......@@ -71,6 +71,11 @@ namespace gum {
std::string super = "" ) = 0;
virtual void addLabel( const std::string& l, std::string extends = "" ) = 0;
virtual void endDiscreteType() = 0;
virtual void startDiscretizedType( const std::string& name ) = 0;
virtual void addTick( double tick ) = 0;
virtual void endDiscretizedType() = 0;
virtual void
addRangeType( const std::string& name, long minVal, long maxVal ) = 0;
virtual void startClass( const std::string& c,
const std::string& extends = "",
const Set<std::string>* implements = nullptr,
......
......@@ -273,8 +273,47 @@ namespace gum {
* discrete type.
*/
virtual void endDiscreteType() override;
/// @}
/**
* Start a discretized type declaration.
*
* @param name The discretized type's name.
*
* @throw DuplicateElement Raised if an object with the same name
* already exists.
*/
virtual void startDiscretizedType( const std::string& name ) override;
/**
* Add a tick to the current discretized type.
*
* @param tick The tick value.
*/
virtual void addTick(double tick) override;
/**
* End the current discretized type declaration.
*
* @throw OperationNotAllowed Raised if the current type is not a valid
* discrete type.
*/
virtual void endDiscretizedType() override;
/**
* Add a range variable type declaration.
*
* @param name The variable's name
* @param minVal The variable's lower bound.
* @param maxVal The variable's upper bound.
*
* @throw DuplicateElement Raised if an object with the same name
* already exists.
* @throw OperationNotAllowed Raised if the range variable is not a valid
* discrete type.
*/
virtual void
addRangeType( const std::string& name, long minVal, long maxVal ) override;
/// @}
///@name several checks for parsers
/// @{
......
......@@ -30,68 +30,15 @@
#include <agrum/core/math/formula.h>
#include <agrum/variables/discretizedVariable.h>
#include <agrum/variables/rangeVariable.h>
#include <agrum/PRM/elements/PRMFormAttribute.h>
#include <agrum/PRM/elements/PRMFuncAttribute.h>
namespace gum {
namespace prm {
template <typename GUM_SCALAR>
INLINE void PRMFactory<GUM_SCALAR>::addLabel( const std::string& l,
std::string extends ) {
if ( extends == "" ) {
PRMType<GUM_SCALAR>* t = static_cast<PRMType<GUM_SCALAR>*>(
__checkStack( 1, PRMObject::prm_type::TYPE ) );
LabelizedVariable* var = dynamic_cast<LabelizedVariable*>( t->__var );
if ( !var ) {
GUM_ERROR( FatalError,
"the current type's variable is not a LabelizedVariable." );
} else if ( t->__superType ) {
GUM_ERROR( OperationNotAllowed, "current type is a subtype." );
}
try {
var->addLabel( l );
} catch ( DuplicateElement& ) {
GUM_ERROR( DuplicateElement,
"a label with the same value already exists" );
}
} else {
PRMType<GUM_SCALAR>* t = static_cast<PRMType<GUM_SCALAR>*>(
__checkStack( 1, PRMObject::prm_type::TYPE ) );
LabelizedVariable* var = dynamic_cast<LabelizedVariable*>( t->__var );
if ( !var ) {
GUM_ERROR( FatalError,
"the current type's variable is not a LabelizedVariable." );
} else if ( !t->__superType ) {
GUM_ERROR( OperationNotAllowed, "current type is not a subtype." );
}
bool found = false;
for ( Idx i = 0; i < t->__superType->__var->domainSize(); ++i ) {
if ( t->__superType->__var->label( i ) == extends ) {
try {
var->addLabel( l );
} catch ( DuplicateElement& ) {
GUM_ERROR( DuplicateElement,
"a label with the same value already exists" );
}
t->__label_map->push_back( i );
found = true;
break;
}
}
if ( !found ) {
GUM_ERROR( NotFound, "inexistent label in super type." );
}
}
}
template <typename GUM_SCALAR>
INLINE void
......@@ -1547,6 +1494,63 @@ namespace gum {
}
}
template <typename GUM_SCALAR>
INLINE void PRMFactory<GUM_SCALAR>::addLabel( const std::string& l,
std::string extends ) {
if ( extends == "" ) {
PRMType<GUM_SCALAR>* t = static_cast<PRMType<GUM_SCALAR>*>(
__checkStack( 1, PRMObject::prm_type::TYPE ) );
LabelizedVariable* var = dynamic_cast<LabelizedVariable*>( t->__var );
if ( !var ) {
GUM_ERROR( FatalError,
"the current type's variable is not a LabelizedVariable." );
} else if ( t->__superType ) {
GUM_ERROR( OperationNotAllowed, "current type is a subtype." );
}
try {
var->addLabel( l );
} catch ( DuplicateElement& ) {
GUM_ERROR( DuplicateElement,
"a label with the same value already exists" );
}
} else {
PRMType<GUM_SCALAR>* t = static_cast<PRMType<GUM_SCALAR>*>(
__checkStack( 1, PRMObject::prm_type::TYPE ) );
LabelizedVariable* var = dynamic_cast<LabelizedVariable*>( t->__var );
if ( !var ) {
GUM_ERROR( FatalError,
"the current type's variable is not a LabelizedVariable." );
} else if ( !t->__superType ) {
GUM_ERROR( OperationNotAllowed, "current type is not a subtype." );
}
bool found = false;
for ( Idx i = 0; i < t->__superType->__var->domainSize(); ++i ) {
if ( t->__superType->__var->label( i ) == extends ) {
try {
var->addLabel( l );
} catch ( DuplicateElement& ) {
GUM_ERROR( DuplicateElement,
"a label with the same value already exists" );
}
t->__label_map->push_back( i );
found = true;
break;
}
}
if ( !found ) {
GUM_ERROR( NotFound, "inexistent label in super type." );
}
}
}
template <typename GUM_SCALAR>
INLINE void PRMFactory<GUM_SCALAR>::endDiscreteType() {
PRMType<GUM_SCALAR>* t = static_cast<PRMType<GUM_SCALAR>*>(
......@@ -1565,6 +1569,77 @@ namespace gum {
__stack.pop_back();
}
template <typename GUM_SCALAR>
INLINE void PRMFactory<GUM_SCALAR>::startDiscretizedType( const std::string& name ) {
std::string real_name = __addPrefix( name );
if ( __prm->__typeMap.exists( real_name ) ) {
std::stringstream msg;
msg << "\"" << real_name << "\" is already used.";
GUM_ERROR( DuplicateElement, msg.str() );
}
auto var = DiscretizedVariable<double>( real_name, "" );
auto t = new PRMType<GUM_SCALAR>( var );
__stack.push_back( t );
}
template <typename GUM_SCALAR>
INLINE void PRMFactory<GUM_SCALAR>::addTick( double tick ) {
PRMType<GUM_SCALAR>* t = static_cast<PRMType<GUM_SCALAR>*>(
__checkStack( 1, PRMObject::prm_type::TYPE ) );
DiscretizedVariable<double>* var =
dynamic_cast<DiscretizedVariable<double>*>( t->__var );
if ( !var ) {
GUM_ERROR( FatalError,
"the current type's variable is not a LabelizedVariable." );
}
try {
var->addTick( tick );
} catch ( DefaultInLabel& e ) {
GUM_ERROR( OperationNotAllowed, "tick already in used for this variable" );
}
}
template <typename GUM_SCALAR>
INLINE void PRMFactory<GUM_SCALAR>::endDiscretizedType() {
PRMType<GUM_SCALAR>* t = static_cast<PRMType<GUM_SCALAR>*>(
__checkStack( 1, PRMObject::prm_type::TYPE ) );
if ( t->variable().domainSize() < 2 ) {
GUM_ERROR( OperationNotAllowed,
"current type is not a valid discrete type" );
}
__prm->__typeMap.insert( t->name(), t );
__prm->__types.insert( t );
__stack.pop_back();
}
template <typename GUM_SCALAR>
INLINE void PRMFactory<GUM_SCALAR>::addRangeType( const std::string& name,
long minVal,
long maxVal ) {
std::string real_name = __addPrefix( name );
if ( __prm->__typeMap.exists( real_name ) ) {
std::stringstream msg;
msg << "\"" << real_name << "\" is already used.";
GUM_ERROR( DuplicateElement, msg.str() );
}
auto var = RangeVariable( real_name, "", minVal, maxVal );
auto t = new PRMType<GUM_SCALAR>( var );
if ( t->variable().domainSize() < 2 ) {
GUM_ERROR( OperationNotAllowed,
"current type is not a valid discrete type" );
}
__prm->__typeMap.insert( t->name(), t );
__prm->__types.insert( t );
}
template <typename GUM_SCALAR>
INLINE void PRMFactory<GUM_SCALAR>::endInterface() {
__checkStack( 1, PRMObject::prm_type::PRM_INTERFACE );
......
......@@ -157,19 +157,9 @@ namespace gum {
PRMFactory<GUM_SCALAR> factory( __prm );
for ( auto type : __o3IntTypes ) {
factory.startDiscreteType( type->name().label() );
factory.addRangeType(
type->name().label(), type->start().value(), type->end().value() );
auto n = type->end().value() - type->start().value();
for ( auto i = 0; i <= n; ++i ) {
std::stringstream s;
s << type->start().value() + i;
factory.addLabel( std::string( s.str() ) );
}
factory.endDiscreteType();
}
}
}
......@@ -182,16 +172,12 @@ namespace gum {
PRMFactory<GUM_SCALAR> factory( __prm );
for ( auto type : __o3RealTypes ) {
factory.startDiscreteType( type->name().label() );
factory.startDiscretizedType( type->name().label() );
for ( std::size_t idx = 1; idx < type->values().size(); ++idx ) {
std::stringstream label;
label << "[" << type->values()[idx - 1].value() << ", "
<< type->values()[idx].value() << "[";
factory.addLabel( label.str() );
for ( auto value : type->values() ) {
factory.addTick( value.value() );
}
factory.endDiscreteType();
factory.endDiscretizedType();
}
}
}
......
......@@ -634,8 +634,8 @@ namespace gum_tests {
TS_ASSERT( prm.isType( "angle" ) );
const auto& angle = prm.type( "angle" );
TS_ASSERT_EQUALS( angle.variable().labels().size(), (gum::Size)2 );
TS_ASSERT_EQUALS( angle.variable().labels().at( 0 ), "[0, 90[" );
TS_ASSERT_EQUALS( angle.variable().labels().at( 1 ), "[90, 180[" );
TS_ASSERT_EQUALS( angle.variable().labels().at( 0 ), "[0;90[" );
TS_ASSERT_EQUALS( angle.variable().labels().at( 1 ), "[90;180]" );
}
void testRealType2() {
......@@ -653,9 +653,9 @@ namespace gum_tests {
TS_ASSERT( prm.isType( "angle" ) );
const auto& angle = prm.type( "angle" );
TS_ASSERT_EQUALS( angle.variable().labels().size(), (gum::Size)3 );
TS_ASSERT_EQUALS( angle.variable().labels().at( 0 ), "[0, 90[" );
TS_ASSERT_EQUALS( angle.variable().labels().at( 1 ), "[90, 180[" );
TS_ASSERT_EQUALS( angle.variable().labels().at( 2 ), "[180, 360[" );
TS_ASSERT_EQUALS( angle.variable().labels().at( 0 ), "[0;90[" );
TS_ASSERT_EQUALS( angle.variable().labels().at( 1 ), "[90;180[" );
TS_ASSERT_EQUALS( angle.variable().labels().at( 2 ), "[180;360]" );
}
void testRealTypeError1() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment