OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-atomspace / tests / query / EvaluationUTest.cxxtest

297 lines · cxxtest ref:
/*
 * 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__);
}