/*
* tests/query/EvaluationUTest.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>
using namespace opencog;
class EvaluationUTest: public CxxTest::TestSuite
{
private:
AtomSpacePtr as;
SchemeEval* eval;
public:
EvaluationUTest(void)
{
logger().set_level(Logger::DEBUG);
logger().set_print_to_stdout_flag(true);
logger().set_sync_flag(true);
as = createAtomSpace();
eval = SchemeEval::get_scheme_evaluator(as);
}
~EvaluationUTest()
{
// 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 do_test_eval(void);
void do_test_logic(void);
void do_test_varval(void);
void test_eval_rw(void);
void test_logic_rw(void);
void test_varval_rw(void);
void test_eval_overlay(void);
void test_logic_overlay(void);
void test_varval_overlay(void);
void test_eval_equal(void);
void test_logic_equal(void);
};
void EvaluationUTest::tearDown(void)
{
as->clear();
}
void EvaluationUTest::setUp(void)
{
as->clear();
eval->eval("(add-to-load-path \"" PROJECT_SOURCE_DIR "\")");
}
#define getarity(hand) hand->get_arity()
/*
* Evaluation most basic unit test.
*/
void EvaluationUTest::do_test_eval(void)
{
Handle five = eval->eval_h("(cog-execute! (five-arcs))");
printf ("five: found:\n%s\n", five->to_short_string().c_str());
TS_ASSERT_EQUALS(5, getarity(five));
Handle one = eval->eval_h("(cog-execute! (one-arc-one))");
printf ("one: found:\n%s\n", one->to_short_string().c_str());
TS_ASSERT_EQUALS(1, getarity(one));
Handle onet = eval->eval_h("(cog-execute! (one-arc-three))");
printf ("onet: found:\n%s\n", onet->to_short_string().c_str());
TS_ASSERT_EQUALS(1, getarity(onet));
Handle zero = eval->eval_h("(cog-execute! (zero-arcs))");
printf ("zero: found:\n%s\n", zero->to_short_string().c_str());
TS_ASSERT_EQUALS(0, getarity(zero));
Handle four = eval->eval_h("(cog-execute! (four-arcs))");
printf ("four: found:\n%s\n", four->to_short_string().c_str());
TS_ASSERT_EQUALS(4, getarity(four));
Handle two = eval->eval_h("(cog-execute! (two-arcs))");
printf ("two: found:\n%s\n", two->to_short_string().c_str());
TS_ASSERT_EQUALS(2, getarity(two));
}
/*
* Evaluation boolean logic unit test.
*/
void EvaluationUTest::do_test_logic(void)
{
Handle four = eval->eval_h("(cog-execute! (four-not))");
printf ("four-not: found:\n%s\n", four->to_short_string().c_str());
TS_ASSERT_EQUALS(4, getarity(four));
Handle two = eval->eval_h("(cog-execute! (two-or))");
printf ("two-or: found:\n%s\n", two->to_short_string().c_str());
TS_ASSERT_EQUALS(2, getarity(two));
Handle three = eval->eval_h("(cog-execute! (three-nor))");
printf ("three-nor: found:\n%s\n", three->to_short_string().c_str());
TS_ASSERT_EQUALS(3, getarity(three));
Handle fancy = eval->eval_h("(cog-execute! (two-fancy))");
printf ("two-fancy: found:\n%s\n", fancy->to_short_string().c_str());
TS_ASSERT_EQUALS(2, getarity(fancy));
// Both the searches should return the same two (the first two)
TS_ASSERT_EQUALS(two, fancy);
}
/*
* Make sure that variables get evaluated when they appear in an
* evaluatable location.
*/
void EvaluationUTest::do_test_varval(void)
{
Handle do_things = eval->eval_h("(do-things)");
printf ("do-pattern: \n%s\n", do_things->to_short_string().c_str());
Handle do_things_results = HandleCast(do_things->execute(as.get()));
printf ("do-things: \n%s\n", do_things_results->to_short_string().c_str());
// Of the two possibilities, we only expect one to pass.
Handle expected = eval->eval_h(
"(SetLink"
" (ImplicationLink"
" (PredicateNode \"acceptance\")"
" (PredicateNode \"acceptance\")))");
TS_ASSERT_EQUALS(expected, do_things_results);
Handle ndostuff = eval->eval_h("(cog-execute! (do-nthings))");
printf ("do-nthings: \n%s\n", ndostuff->to_short_string().c_str());
// Of the two possibilities, we only expect one to pass.
Handle rejected = eval->eval_h(
"(SetLink"
" (ImplicationLink"
" (PredicateNode \"rejection\")"
" (PredicateNode \"rejection\")))");
TS_ASSERT_EQUALS(rejected, ndostuff);
Handle nndostuff = eval->eval_h("(cog-execute! (do-nnthings))");
printf ("do-nnthings: \n%s\n", nndostuff->to_short_string().c_str());
// Of the two possibilities, we only expect one to pass.
TS_ASSERT_EQUALS(expected, nndostuff);
}
void EvaluationUTest::test_eval_rw(void)
{
logger().debug("BEGIN TEST: %s", __FUNCTION__);
eval->eval("(load-from-path \"tests/query/evaluation.scm\")");
do_test_eval();
logger().debug("END TEST: %s", __FUNCTION__);
}
void EvaluationUTest::test_logic_rw(void)
{
logger().debug("BEGIN TEST: %s", __FUNCTION__);
eval->eval("(load-from-path \"tests/query/evaluation.scm\")");
do_test_logic();
logger().debug("END TEST: %s", __FUNCTION__);
}
void EvaluationUTest::test_varval_rw(void)
{
logger().debug("BEGIN TEST: %s", __FUNCTION__);
eval->eval("(load-from-path \"tests/query/eval-var.scm\")");
do_test_varval();
logger().debug("END TEST: %s", __FUNCTION__);
}
void EvaluationUTest::test_eval_overlay(void)
{
logger().debug("BEGIN TEST: %s", __FUNCTION__);
eval->eval("(load-from-path \"tests/query/evaluation.scm\")");
// Mark base-space as readonly; create a read-write overlay.
as->set_read_only();
AtomSpacePtr save = as;
as = createAtomSpace(as);
SchemeEval* seval = eval;
eval = SchemeEval::get_scheme_evaluator(as);
do_test_eval();
eval = seval;
as = save;
as->set_read_write();
logger().debug("END TEST: %s", __FUNCTION__);
}
void EvaluationUTest::test_logic_overlay(void)
{
logger().debug("BEGIN TEST: %s", __FUNCTION__);
eval->eval("(load-from-path \"tests/query/evaluation.scm\")");
// Mark base-space as readonly; create a read-write overlay.
as->set_read_only();
AtomSpacePtr save = as;
as = createAtomSpace(as);
SchemeEval* seval = eval;
eval = SchemeEval::get_scheme_evaluator(as);
do_test_logic();
eval = seval;
as = save;
as->set_read_write();
logger().debug("END TEST: %s", __FUNCTION__);
}
void EvaluationUTest::test_varval_overlay(void)
{
logger().debug("BEGIN TEST: %s", __FUNCTION__);
eval->eval("(load-from-path \"tests/query/eval-var.scm\")");
// Mark base-space as readonly; create a read-write overlay.
as->set_read_only();
AtomSpacePtr save = as;
as = createAtomSpace(as);
SchemeEval* seval = eval;
eval = SchemeEval::get_scheme_evaluator(as);
do_test_varval();
eval = seval;
as = save;
as->set_read_write();
logger().debug("END TEST: %s", __FUNCTION__);
}
// Identical to test_eval_rw, except it uses EqualLink not IdenticalLink
void EvaluationUTest::test_eval_equal(void)
{
logger().debug("BEGIN TEST: %s", __FUNCTION__);
eval->eval("(load-from-path \"tests/query/eval-equal.scm\")");
do_test_eval();
logger().debug("END TEST: %s", __FUNCTION__);
}
// Identical to test_logic_rw, except it uses EqualLink not IdenticalLink
void EvaluationUTest::test_logic_equal(void)
{
logger().debug("BEGIN TEST: %s", __FUNCTION__);
eval->eval("(load-from-path \"tests/query/eval-equal.scm\")");
do_test_logic();
logger().debug("END TEST: %s", __FUNCTION__);
}