OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-atomspace / tests / query / ConstantClausesUTest.cxxtest

306 lines · cxxtest ref:
/*
 * tests/query/ConstantClausesUTest.cxxtest
 *
 * Copyright (C) 2017 OpenCog Foundation
 * All Rights Reserved
 * Author: Nil Geisweiller
 *
 * 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>

using namespace std;
using namespace opencog;

#define al as->add_link
#define an as->add_node

class ConstantClausesUTest: public CxxTest::TestSuite
{
private:
	AtomSpacePtr as;
	SchemeEval* eval;
	Handle A, B, C, AB, IdAA, P, Q, X, LP, LQ;

public:
	ConstantClausesUTest() : as(createAtomSpace()), eval(SchemeEval::get_scheme_evaluator(as))
	{
		logger().set_level(Logger::DEBUG);
		logger().set_timestamp_flag(false);
		logger().set_print_to_stdout_flag(true);

		string dir = string(PROJECT_SOURCE_DIR) + "/tests/query";
		eval->eval(string("(add-to-load-path \"") + dir + string("\")"));
	}

	~ConstantClausesUTest()
	{
		// Erase the log file if no assertions failed.
		if (!CxxTest::TestTracker::tracker().suiteFailed())
				std::remove(logger().get_filename().c_str());
	}

	void setUp();
	void tearDown();

	void test_constant_1();
	void test_constant_2();
	void test_constant_3();
	void test_evaluatable_1();
	void test_evaluatable_2();
	void test_evaluatable_3();
	void test_constant_evaluatable_1();
	void test_constant_evaluatable_2();
	void test_constant_pattern();
	void test_mixed_clauses_1();
	void test_mixed_clauses_2();
	void test_mixed_clauses_3();
};

void ConstantClausesUTest::tearDown()
{
	as->clear();
}

void ConstantClausesUTest::setUp()
{
	A = an(CONCEPT_NODE, "A");
	B = an(CONCEPT_NODE, "B");
	C = an(CONCEPT_NODE, "C");
	AB = al(INHERITANCE_LINK, A, B);
	IdAA = al(IDENTICAL_LINK, A, A);
	P = an(PREDICATE_NODE, "P");
	Q = an(PREDICATE_NODE, "Q");
	X = an(VARIABLE_NODE, "$X");
	LP = al(LAMBDA_LINK, X, al(EVALUATION_LINK, P));
	LQ = al(LAMBDA_LINK, X, al(EVALUATION_LINK, Q));
}

/*
 * Simple Concept as constant clause.
 */
void ConstantClausesUTest::test_constant_1()
{
	logger().debug("BEGIN TEST: %s", __FUNCTION__);
	Handle bl = al(COLLECTION_OF_LINK, al(QUERY_LINK, A, B)),
		result = HandleCast(bl->execute(as.get())),
		expected = al(SET_LINK, B);
	TS_ASSERT_EQUALS(result, expected);
	logger().debug("END TEST: %s", __FUNCTION__);
}

/*
 * Simple Inheritance link as constant clause.
 */
void ConstantClausesUTest::test_constant_2()
{
	logger().debug("BEGIN TEST: %s", __FUNCTION__);
	Handle bl = al(COLLECTION_OF_LINK, al(QUERY_LINK, AB, C)),
		result = HandleCast(bl->execute(as.get())),
		expected = al(SET_LINK, C);
	TS_ASSERT_EQUALS(result, expected);
	logger().debug("END TEST: %s", __FUNCTION__);
}

/*
 * Conjunction of Concept and Inheritance as constant clauses.
 */
void ConstantClausesUTest::test_constant_3()
{
	logger().debug("BEGIN TEST: %s", __FUNCTION__);
	Handle bl = al(COLLECTION_OF_LINK, al(QUERY_LINK, al(AND_LINK, AB, A), C)),
		result = HandleCast(bl->execute(as.get())),
		expected = al(SET_LINK, C);
	TS_ASSERT_EQUALS(result, expected);
	logger().debug("END TEST: %s", __FUNCTION__);
}

/*
 * Simple clause with an evaluatable constant clause that is true (so
 * the rewrite term should be triggered).
 */
void ConstantClausesUTest::test_evaluatable_1()
{
	logger().debug("BEGIN TEST: %s", __FUNCTION__);
	Handle bl = al(COLLECTION_OF_LINK, al(QUERY_LINK, IdAA, B)),
		result = HandleCast(bl->execute(as.get())),
		expected = al(SET_LINK, B);
	TS_ASSERT_EQUALS(result, expected);
	logger().debug("END TEST: %s", __FUNCTION__);
}

/*
 * Simple clause with an evaluatable constant clause that is false (so
 * the rewrite term should not be triggered).
 */
void ConstantClausesUTest::test_evaluatable_2()
{
	logger().debug("BEGIN TEST: %s", __FUNCTION__);
	Handle bl = al(COLLECTION_OF_LINK, al(QUERY_LINK, al(NOT_LINK, IdAA), B)),
		result = HandleCast(bl->execute(as.get())),
		expected = al(SET_LINK);
	TS_ASSERT_EQUALS(result, expected);
	logger().debug("END TEST: %s", __FUNCTION__);
}

/*
 * Simple clause with an evaluatable constant clause that is false (so
 * the rewrite term should not be triggered).
 */
void ConstantClausesUTest::test_evaluatable_3()
{
	logger().debug("BEGIN TEST: %s", __FUNCTION__);
	Handle bl = al(COLLECTION_OF_LINK, al(QUERY_LINK, al(AND_LINK, IdAA, al(NOT_LINK, IdAA)), B)),
		result = HandleCast(bl->execute(as.get())),
		expected = al(SET_LINK);
	TS_ASSERT_EQUALS(result, expected);
	logger().debug("END TEST: %s", __FUNCTION__);
}

/*
 * Simple Concept as constant clause with an evaluatable constant
 * clause that is true (so the rewrite term should be triggered).
 */
void ConstantClausesUTest::test_constant_evaluatable_1()
{
	logger().debug("BEGIN TEST: %s", __FUNCTION__);
	Handle bl = al(COLLECTION_OF_LINK, al(QUERY_LINK, al(AND_LINK, A, IdAA), B)),
		result = HandleCast(bl->execute(as.get())),
		expected = al(SET_LINK, B);
	printf("  Found : %s\n", result->to_string().c_str());
	printf("Expected: %s\n", expected->to_string().c_str());
	TS_ASSERT_EQUALS(result, expected);
	logger().debug("END TEST: %s", __FUNCTION__);
}

/*
 * Simple Concept as constant clause with a evaluatable constant
 * clause that is false (so the rewrite term should not be triggered).
 */
void ConstantClausesUTest::test_constant_evaluatable_2()
{
	logger().debug("BEGIN TEST: %s", __FUNCTION__);
	Handle bl = al(COLLECTION_OF_LINK, al(QUERY_LINK, al(AND_LINK, A, al(NOT_LINK, IdAA)), B)),
		result = HandleCast(bl->execute(as.get())),
		expected = al(SET_LINK);
	TS_ASSERT_EQUALS(result, expected);
	logger().debug("END TEST: %s", __FUNCTION__);
}

/**
 * Constant clauses in a child atomspace would be expected not to be
 * accessible from the parent atomspace, so the rewrite term would not
 * be triggered, however constant clause are removed, regardless of
 * whether they belong to the queried atomspace or not, thus, since
 * empty is synonymous to true, the rewrite term is triggered.
 */
void ConstantClausesUTest::test_constant_pattern()
{
	logger().debug("BEGIN TEST: %s", __FUNCTION__);
	AtomSpacePtr derived_as(as);
	Handle DA = derived_as->add_node(CONCEPT_NODE, "DA"),
		DB = derived_as->add_node(CONCEPT_NODE, "DB"),
		bl = derived_as->add_link(COLLECTION_OF_LINK,
		                         derived_as->add_link(QUERY_LINK,
		                                             derived_as->add_link(INHERITANCE_LINK, DA, DB),
		                                             DB)),
		result = HandleCast(bl->execute(as.get())),
		expected = al(SET_LINK, DB);
	TS_ASSERT_EQUALS(result, expected);
	logger().debug("END TEST: %s", __FUNCTION__);
}

/**
 * Clauses consisting of both ungrounded and grounded (constant)
 * clauses should trigger the rewrite term properly.
 */
void ConstantClausesUTest::test_mixed_clauses_1()
{
	logger().debug("BEGIN TEST: %s", __FUNCTION__);
	Handle mary = an(CONCEPT_NODE, "Mary"),
		edward = an(CONCEPT_NODE, "Edward");

	eval->eval("(load-from-path \"constant-clauses.scm\")");

	Handle result = eval->eval_h("(cog-execute! mixed-clauses)"),
		expected = al(SET_LINK, edward, mary);

	TS_ASSERT_EQUALS(result, expected);
	logger().debug("END TEST: %s", __FUNCTION__);
}

/**
 * Clauses consisting of ungrounded, grounded (constant) and virtual
 * clauses.
 */
void ConstantClausesUTest::test_mixed_clauses_2()
{
	logger().debug("BEGIN TEST: %s", __FUNCTION__);
	eval->eval("(load-from-path \"blair-witch.scm\")");

	Handle query = eval->eval_h("find-something");
	Handle result = HandleCast(query->execute(as.get()));
	Handle expected = al(SET_LINK, A);

	logger().debug() << "y result = " << oc_to_string(result);
	logger().debug() << "expected = " << oc_to_string(expected);

	TS_ASSERT_EQUALS(result, expected);

	query = eval->eval_h("find-nothing"),
	result = HandleCast(query->execute(as.get())),
	expected = al(SET_LINK);

	logger().debug() << "n result = " << oc_to_string(result);
	logger().debug() << "expected = " << oc_to_string(expected);

	TS_ASSERT_EQUALS(result, expected);
	logger().debug("END TEST: %s", __FUNCTION__);
}

/**
 * Clauses consisting of ungrounded, grounded (constant).
 */
void ConstantClausesUTest::test_mixed_clauses_3()
{
	logger().debug("BEGIN TEST: %s", __FUNCTION__);
	eval->eval("(load-from-path \"constant-scope.scm\")");

	Handle query = eval->eval_h("query"),
		result = HandleCast(query->execute(as.get())),
		expected = eval->eval_h("expected");
	HandleSet results(result->getOutgoingSet().begin(),
	                  result->getOutgoingSet().end()),
		more_expected(expected->getOutgoingSet().begin(),
		              expected->getOutgoingSet().end());

	// Add the other LambdaLinks
	more_expected.insert(LP);
	more_expected.insert(LQ);

	logger().debug() << "results = " << oc_to_string(results);
	logger().debug() << "more_expected = " << oc_to_string(more_expected);

	TS_ASSERT_EQUALS(results, more_expected);
	logger().debug("END TEST: %s", __FUNCTION__);
}

#undef al
#undef an