/*
* tests/atoms/flow/DynamicUTest.cxxtest
*
* Copyright (C) 2020 Linas Vepstas
* All Rights Reserved
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#include <stdlib.h>
#include <opencog/guile/SchemeEval.h>
#include <opencog/atoms/base/Atom.h>
#include <opencog/atoms/value/FloatValue.h>
#include <opencog/atomspace/AtomSpace.h>
#include <opencog/util/Logger.h>
#include <cxxtest/TestSuite.h>
using namespace opencog;
#define al _as.add_link
#define an _as.add_node
class DynamicUTest : public CxxTest::TestSuite
{
private:
AtomSpacePtr _asp;
SchemeEval* _eval;
public:
DynamicUTest(void);
void setUp(void);
void check(void);
void test_predicate_formula();
void test_formula_define();
void test_dynamic_predicate();
void test_defined_dynamic();
void test_formula_stream();
void test_futures();
};
DynamicUTest::DynamicUTest(void) : _asp(createAtomSpace()), _eval(SchemeEval::get_scheme_evaluator(_asp))
{
logger().set_level(Logger::DEBUG);
logger().set_print_to_stdout_flag(true);
logger().set_timestamp_flag(false);
logger().set_sync_flag(true);
_eval->eval("(add-to-load-path \"" PROJECT_SOURCE_DIR "\")");
_eval->eval("(load-from-path \"tests/atoms/flow/dynamic.scm\")");
}
void DynamicUTest::setUp(void)
{
}
#define EPSI 1.0e-8
// ====================================================================
// Basic FutureTruthValue
void DynamicUTest::test_predicate_formula()
{
logger().debug("BEGIN TEST: %s", __FUNCTION__);
ValuePtr result = _eval->eval_v("fututv");
// printf("result: %s\n", result->to_string().c_str());
printf("Got type=%s\n",
nameserver().getTypeName(result->get_type()).c_str());
TS_ASSERT_EQUALS(result->get_type(), FORMULA_STREAM);
TS_ASSERT(result->is_type(FLOAT_VALUE));
FloatValuePtr stv = FloatValueCast(result);
// printf("stv: %s\n", stv->to_string().c_str());
_eval->eval("(set-fake-tv! A (FloatValue 0.1 0.9))");
_eval->eval("(set-fake-tv! B (FloatValue 0.1 0.9))");
TS_ASSERT(fabs(stv->value()[0] - 0.99) <= EPSI);
TS_ASSERT(fabs(stv->value()[1] - 0.81) <= EPSI);
_eval->eval("(set-fake-tv! A (FloatValue 0.2 0.8))");
_eval->eval("(set-fake-tv! B (FloatValue 0.1 0.9))");
TS_ASSERT(fabs(stv->value()[0] - 0.98) <= EPSI);
TS_ASSERT(fabs(stv->value()[1] - 0.72) <= EPSI);
_eval->eval("(set-fake-tv! A (FloatValue 0.2 0.8))");
_eval->eval("(set-fake-tv! B (FloatValue 0.3 0.7))");
TS_ASSERT(fabs(stv->value()[0] - 0.94) <= EPSI);
TS_ASSERT(fabs(stv->value()[1] - 0.56) <= EPSI);
_eval->eval("(set-fake-tv! A (FloatValue 0.4 0.6))");
_eval->eval("(set-fake-tv! B (FloatValue 0.1 0.9))");
TS_ASSERT(fabs(stv->value()[0] - 0.96) <= EPSI);
TS_ASSERT(fabs(stv->value()[1] - 0.54) <= EPSI);
logger().debug("END TEST: %s", __FUNCTION__);
}
// ====================================================================
// Basic FutureTruthValue
void DynamicUTest::test_formula_define()
{
logger().debug("BEGIN TEST: %s", __FUNCTION__);
ValuePtr result = _eval->eval_v("tv-stream");
// printf("result: %s\n", result->to_string().c_str());
printf("Got type=%s\n",
nameserver().getTypeName(result->get_type()).c_str());
TS_ASSERT_EQUALS(result->get_type(), FORMULA_STREAM);
TS_ASSERT(result->is_type(FLOAT_VALUE));
FloatValuePtr stv = FloatValueCast(result);
// printf("stv: %s\n", stv->to_string().c_str());
_eval->eval("(set-fake-tv! A (FloatValue 0.1 0.9))");
_eval->eval("(set-fake-tv! B (FloatValue 0.1 0.9))");
TS_ASSERT(fabs(stv->value()[0] - 0.99) <= EPSI);
TS_ASSERT(fabs(stv->value()[1] - 0.81) <= EPSI);
_eval->eval("(set-fake-tv! A (FloatValue 0.2 0.8))");
_eval->eval("(set-fake-tv! B (FloatValue 0.1 0.9))");
TS_ASSERT(fabs(stv->value()[0] - 0.98) <= EPSI);
TS_ASSERT(fabs(stv->value()[1] - 0.72) <= EPSI);
_eval->eval("(set-fake-tv! A (FloatValue 0.2 0.8))");
_eval->eval("(set-fake-tv! B (FloatValue 0.3 0.7))");
TS_ASSERT(fabs(stv->value()[0] - 0.94) <= EPSI);
TS_ASSERT(fabs(stv->value()[1] - 0.56) <= EPSI);
_eval->eval("(set-fake-tv! A (FloatValue 0.4 0.6))");
_eval->eval("(set-fake-tv! B (FloatValue 0.1 0.9))");
TS_ASSERT(fabs(stv->value()[0] - 0.96) <= EPSI);
TS_ASSERT(fabs(stv->value()[1] - 0.54) <= EPSI);
logger().debug("END TEST: %s", __FUNCTION__);
}
// ====================================================================
// Verify that PromisePredicate create FutureTV
void DynamicUTest::test_dynamic_predicate()
{
logger().debug("BEGIN TEST: %s", __FUNCTION__);
ValuePtr result = _eval->eval_v("(fake-tv a-implies-b)");
// printf("result: %s\n", result->to_string().c_str());
printf("Got type=%s\n",
nameserver().getTypeName(result->get_type()).c_str());
TS_ASSERT_EQUALS(result->get_type(), FORMULA_STREAM);
TS_ASSERT(result->is_type(FLOAT_VALUE));
FloatValuePtr stv = FloatValueCast(result);
// printf("stv: %s\n", stv->to_string().c_str());
_eval->eval("(set-fake-tv! A (FloatValue 0.1 0.9))");
_eval->eval("(set-fake-tv! B (FloatValue 0.1 0.9))");
TS_ASSERT(fabs(stv->value()[0] - 0.99) <= EPSI);
TS_ASSERT(fabs(stv->value()[1] - 0.81) <= EPSI);
_eval->eval("(set-fake-tv! A (FloatValue 0.2 0.8))");
_eval->eval("(set-fake-tv! B (FloatValue 0.1 0.9))");
TS_ASSERT(fabs(stv->value()[0] - 0.98) <= EPSI);
TS_ASSERT(fabs(stv->value()[1] - 0.72) <= EPSI);
_eval->eval("(set-fake-tv! A (FloatValue 0.2 0.8))");
_eval->eval("(set-fake-tv! B (FloatValue 0.3 0.7))");
TS_ASSERT(fabs(stv->value()[0] - 0.94) <= EPSI);
TS_ASSERT(fabs(stv->value()[1] - 0.56) <= EPSI);
_eval->eval("(set-fake-tv! A (FloatValue 0.4 0.6))");
_eval->eval("(set-fake-tv! B (FloatValue 0.1 0.9))");
TS_ASSERT(fabs(stv->value()[0] - 0.96) <= EPSI);
TS_ASSERT(fabs(stv->value()[1] - 0.54) <= EPSI);
logger().debug("END TEST: %s", __FUNCTION__);
}
// ====================================================================
// Same as above, but with predicate
void DynamicUTest::test_defined_dynamic()
{
logger().debug("BEGIN TEST: %s", __FUNCTION__);
ValuePtr result = _eval->eval_v("(fake-tv p-implies-q)");
// printf("result: %s\n", result->to_string().c_str());
printf("Got type=%s\n",
nameserver().getTypeName(result->get_type()).c_str());
TS_ASSERT_EQUALS(result->get_type(), FORMULA_STREAM);
TS_ASSERT(result->is_type(FLOAT_VALUE));
FloatValuePtr stv = FloatValueCast(result);
// printf("stv: %s\n", stv->to_string().c_str());
_eval->eval("(set-fake-tv! A (FloatValue 0.1 0.9))");
_eval->eval("(set-fake-tv! B (FloatValue 0.1 0.9))");
TS_ASSERT(fabs(stv->value()[0] - 0.99) <= EPSI);
TS_ASSERT(fabs(stv->value()[1] - 0.81) <= EPSI);
_eval->eval("(set-fake-tv! A (FloatValue 0.2 0.8))");
_eval->eval("(set-fake-tv! B (FloatValue 0.1 0.9))");
TS_ASSERT(fabs(stv->value()[0] - 0.98) <= EPSI);
TS_ASSERT(fabs(stv->value()[1] - 0.72) <= EPSI);
_eval->eval("(set-fake-tv! A (FloatValue 0.2 0.8))");
_eval->eval("(set-fake-tv! B (FloatValue 0.3 0.7))");
TS_ASSERT(fabs(stv->value()[0] - 0.94) <= EPSI);
TS_ASSERT(fabs(stv->value()[1] - 0.56) <= EPSI);
_eval->eval("(set-fake-tv! A (FloatValue 0.4 0.6))");
_eval->eval("(set-fake-tv! B (FloatValue 0.1 0.9))");
TS_ASSERT(fabs(stv->value()[0] - 0.96) <= EPSI);
TS_ASSERT(fabs(stv->value()[1] - 0.54) <= EPSI);
logger().debug("END TEST: %s", __FUNCTION__);
}
// ====================================================================
// Formula stream
void DynamicUTest::test_formula_stream()
{
logger().debug("BEGIN TEST: %s", __FUNCTION__);
ValuePtr result = _eval->eval_v("(cog-value bar bkey)");
printf("result: %s\n", result->to_string().c_str());
printf("Got type=%s\n",
nameserver().getTypeName(result->get_type()).c_str());
TS_ASSERT_EQUALS(result->get_type(), FORMULA_STREAM);
Handle foo = _asp->xget_handle(CONCEPT_NODE, "foo");
Handle akey = _asp->xget_handle(PREDICATE_NODE, "some key");
for (int i=0; i<10; i++)
{
std::vector<double> rv;
for (int k=0; k<5; k++)
rv.push_back(((double) random()) / RAND_MAX);
foo->setValue(akey, createFloatValue(std::vector<double>(rv)));
ValuePtr vp = _eval->eval_v("(cog-value bar bkey)");
TS_ASSERT_EQUALS(vp->get_type(), FORMULA_STREAM);
FloatValuePtr fvp = FloatValueCast(vp);
std::vector<double> result = fvp->value();
TS_ASSERT_EQUALS(result.size(), 5);
for (int k=0; k<5; k++)
{
// printf("i=%d idx=%d Got %f vs %f\n", i, k, result[k], rv[k]);
TS_ASSERT(fabs(result[k] - rv[k] - 10.0) <= EPSI);
}
}
logger().debug("END TEST: %s", __FUNCTION__);
}
// ====================================================================
// Test the flow-dutures.scm example.
void DynamicUTest::test_futures()
{
logger().debug("BEGIN TEST: %s", __FUNCTION__);
_eval->eval("(load-from-path \"tests/atoms/flow/futures.scm\")");
ValuePtr scalar = _eval->eval_v("(get-mi-scalar \"hello\" \"world\")");
printf("scalar: %s\n", scalar->to_string().c_str());
FloatValuePtr fvp = FloatValueCast(scalar);
TS_ASSERT(nullptr != fvp);
double smi = fvp->value()[0];
TS_ASSERT(fabs(smi - 0.7369655941662062) <= EPSI);
ValuePtr flvect = _eval->eval_v("(get-mi-stream \"hello\" \"world\")");
printf("flvect: %s\n", flvect->to_string().c_str());
fvp = FloatValueCast(flvect);
TS_ASSERT(nullptr != fvp);
double vmi = fvp->value()[2];
TS_ASSERT(fabs(vmi - 0.7369655941662062) <= EPSI);
// Bump the numbers
_eval->eval("(observe \"Hey\" \"Joe\")");
_eval->eval("(observe \"whazzup\" \"Joe\")");
scalar = _eval->eval_v("(get-mi-scalar \"hello\" \"world\")");
printf("scalar: %s\n", scalar->to_string().c_str());
fvp = FloatValueCast(scalar);
TS_ASSERT(nullptr != fvp);
smi = fvp->value()[0];
TS_ASSERT(fabs(smi - 1.222392421336448) <= EPSI);
flvect = _eval->eval_v("(get-mi-stream \"hello\" \"world\")");
printf("flvect: %s\n", flvect->to_string().c_str());
fvp = FloatValueCast(flvect);
TS_ASSERT(nullptr != fvp);
vmi = fvp->value()[2];
TS_ASSERT(fabs(vmi - 1.222392421336448) <= EPSI);
logger().debug("END TEST: %s", __FUNCTION__);
}
// ====================================================================