/*
* tests/atoms/RandomUTest.cxxtest
*
* Copyright (C) 2015 Linas Vepstas
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License v3 as
* published by the Free Software Foundation and including the exceptions
* at http://opencog.org/wiki/Licenses
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program; if not, write to:
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <opencog/guile/SchemeEval.h>
#include <opencog/atomspace/AtomSpace.h>
#include <opencog/util/Logger.h>
#include <opencog/atoms/value/BoolValue.h>
#include <opencog/atoms/value/LinkValue.h>
using namespace opencog;
class RandomUTest: public CxxTest::TestSuite
{
private:
AtomSpacePtr as;
SchemeEval* eval;
public:
RandomUTest(void)
{
logger().set_level(Logger::DEBUG);
logger().set_print_to_stdout_flag(true);
as = createAtomSpace();
eval = SchemeEval::get_scheme_evaluator(as);
eval->eval("(add-to-load-path \"" PROJECT_SOURCE_DIR "\")");
}
~RandomUTest()
{
// Erase the log file if no assertions failed.
if (!CxxTest::TestTracker::tracker().suiteFailed())
std::remove(logger().get_filename().c_str());
}
void setUp(void);
void tearDown(void);
void test_weights(void);
void test_pairs(void);
};
void RandomUTest::tearDown(void)
{
as->clear();
}
void RandomUTest::setUp(void)
{
as->clear();
}
/*
* RandomChoiceLink unit test.
*/
void RandomUTest::test_weights(void)
{
logger().debug("BEGIN TEST: %s", __FUNCTION__);
eval->eval("(load-from-path \"tests/atoms/random-choice.scm\")");
eval->eval_v("(cog-execute! (DefinedPredicate \"loop a lot of times\"))");
ValuePtr vcountA = eval->eval_v(
"(cog-execute! (Meet (State (Anchor \"sum-A\") (Variable \"$x\"))))");
LinkValuePtr lvcountA = LinkValueCast(vcountA);
Handle countA = HandleCast(lvcountA->value()[0]);
printf("A-count = %s\n", countA->to_string().c_str());
ValuePtr vcountB = eval->eval_v(
"(cog-execute! (Meet (State (Anchor \"sum-B\") (Variable \"$x\"))))");
LinkValuePtr lvcountB = LinkValueCast(vcountB);
Handle countB = HandleCast(lvcountB->value()[0]);
printf("B-count = %s\n", countB->to_string().c_str());
Handle ratio = eval->eval_h(
"(cog-execute! (DefinedProcedure \"ratio\"))");
printf("ratio = %s\n", ratio->to_string().c_str());
ValuePtr vp = eval->eval_v("(cog-execute! (DefinedPredicate \"test\"))");
BoolValuePtr bvp = BoolValueCast(vp);
TS_ASSERT(bvp->get_bit(0));
logger().debug("END TEST: %s", __FUNCTION__);
}
/*
* RandomChoiceLink unit test.
*/
void RandomUTest::test_pairs(void)
{
logger().debug("BEGIN TEST: %s", __FUNCTION__);
// Define a simple list of pairs
eval->eval_h(
"(DefineLink (DefinedProcedure \"pairs\") "
"(RandomChoice "
" (SetLink "
" (ListLink (NumberNode 1) (Concept \"AAA\"))"
" (ListLink (NumberNode 1) (Concept \"BBB\"))"
" (ListLink (NumberNode 0.1) (Concept \"CCC\")) )))"
);
Handle A = eval->eval_h("(Concept \"AAA\")");
Handle B = eval->eval_h("(Concept \"BBB\")");
Handle C = eval->eval_h("(Concept \"CCC\")");
int cntA=0, cntB=0, cntC=0;
for (int i=0; i<1000; i++)
{
Handle pick = eval->eval_h(
"(cog-execute! (DefinedProcedure \"pairs\"))");
if (pick == A) cntA++;
if (pick == B) cntB++;
if (pick == C) cntC++;
}
printf("Got counts A=%d B=%d C=%d\n", cntA, cntB, cntC);
// Loose bounds. My rand gen always gives the same answer:
// Got counts A=488 B=468 C=44
TS_ASSERT_LESS_THAN(450, cntA);
TS_ASSERT_LESS_THAN(450, cntB);
TS_ASSERT_LESS_THAN(35, cntC);
TS_ASSERT_LESS_THAN(cntA, 500);
TS_ASSERT_LESS_THAN(cntB, 500);
TS_ASSERT_LESS_THAN(cntC, 60);
logger().debug("END TEST: %s", __FUNCTION__);
}