OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-atomspace / tests / atoms / scope / RewriteLinkUTest.cxxtest

307 lines · cxxtest ref:
/*
 * tests/atoms/RewriteLinkUTest.cxxtest
 *
 * Copyright (C) 2017 OpenCog Foundation
 * 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/atoms/base/Atom.h>
#include <opencog/atoms/base/Node.h>
#include <opencog/atoms/base/Link.h>
#include <opencog/atomspace/AtomSpace.h>
#include <opencog/atoms/scope/RewriteLink.h>


#include <cxxtest/TestSuite.h>

using namespace opencog;

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

// Test RewriteLink.
//
class RewriteLinkUTest :  public CxxTest::TestSuite
{
private:
	AtomSpacePtr _asp;
	AtomSpacePtr _asa;
	AtomSpacePtr _asb;
	SchemeEval* _eval;
	Handle X, Y, P, Q, CT;

public:
	RewriteLinkUTest() :
		_asp(createAtomSpace()),
		_asa(createAtomSpace()),
		_asb(createAtomSpace()),
		_eval(SchemeEval::get_scheme_evaluator(_asp))
	{
		logger().set_level(Logger::INFO);
		logger().set_print_to_stdout_flag(true);
		logger().set_timestamp_flag(false);

		X = an(VARIABLE_NODE, "$X");
		Y = an(VARIABLE_NODE, "$Y");
		P = an(PREDICATE_NODE, "P");
		Q = an(PREDICATE_NODE, "Q");
		CT = an(TYPE_NODE, "ConceptNode");

		_eval->eval("(add-to-load-path \"" PROJECT_SOURCE_DIR "\")");

	}

	void setUp() {}

	void tearDown() {}

	void test_unordered();
	void test_beta_reduce_1();
	void test_beta_reduce_2();
	void test_consume_quotations_1();
	void test_consume_quotations_2();
	void test_consume_quotations_3();
	void test_consume_quotations_4();
	void test_consume_quotations_5();
};

#define NA _asa->add_node
#define LA _asa->add_link

#define NB _asb->add_node
#define LB _asb->add_link

// Test RewriteLink::is_equal with unordered links
void RewriteLinkUTest::test_unordered()
{
	logger().info("BEGIN TEST: %s", __FUNCTION__);

	Handle
		X = NA(VARIABLE_NODE, "$X-origin"),
		Y = NA(VARIABLE_NODE, "$Y-origin"),
		Z = NA(VARIABLE_NODE, "$Z-origin"),
		and1 = LA(AND_LINK, X, Y),
		and2 = LA(AND_LINK, Z, Y),
		vardecl = LA(VARIABLE_LIST, X, Y, Z),
		body = LA(OR_LINK, and1, and2),
		sc = LA(REWRITE_LINK, vardecl, body);

	RewriteLinkPtr sc_p(RewriteLinkCast(sc));
	TS_ASSERT(sc_p != nullptr);

	Handle
		alpha_X = NA(VARIABLE_NODE, "$X-alpha"),
		alpha_Y = NA(VARIABLE_NODE, "$Y-alpha"),
		alpha_Z = NA(VARIABLE_NODE, "$Z-alpha"),
		alpha_and2 = LA(AND_LINK, alpha_Z, alpha_Y),
		alpha_and1 = LA(AND_LINK, alpha_X, alpha_Y),
		alpha_vardecl = LA(VARIABLE_LIST, alpha_X, alpha_Y, alpha_Z),
		alpha_body = LA(OR_LINK, alpha_and1, alpha_and2),
		alpha_sc = LA(REWRITE_LINK, alpha_vardecl, alpha_body);

	std::cout << "sc = " << oc_to_string(sc);
	std::cout << "alpha_sc = " << oc_to_string(alpha_sc);
	
	TS_ASSERT(sc_p->is_equal(alpha_sc));

	logger().info("END TEST: %s", __FUNCTION__);
}
// Test RewriteLink::beta_reduce with duplicated variable names
void RewriteLinkUTest::test_beta_reduce_1()
{
	logger().info("BEGIN TEST: %s", __FUNCTION__);

	// Test simple RewriteLink
	Handle X = createNode(VARIABLE_NODE, "$X"),
		Y = createNode(VARIABLE_NODE, "$Y"),
		Z = createNode(VARIABLE_NODE, "$Z"),
		hsc = createLink(REWRITE_LINK,
		                 createLink(VARIABLE_LIST, X, Y),
		                 createLink(INHERITANCE_LINK, X, Y));

	RewriteLinkPtr sc(RewriteLinkCast(hsc));
	Handle result = sc->beta_reduce(HandleMap{{X, Z}, {Y, Z}}),
		expected = createLink(REWRITE_LINK, Z, createLink(INHERITANCE_LINK, Z, Z));

	std::cout << "result = " << oc_to_string(result);
	std::cout << "expected = " << oc_to_string(expected);

	TS_ASSERT(content_eq(result, expected));

	logger().info("END TEST: %s", __FUNCTION__);
}

// Test RewriteLink::beta_reduce with no variable
void RewriteLinkUTest::test_beta_reduce_2()
{
	logger().info("BEGIN TEST: %s", __FUNCTION__);

	// Test simple RewriteLink
	Handle hsc = createLink(REWRITE_LINK,
	                        createLink(VARIABLE_LIST, X, Y),
	                        createLink(INHERITANCE_LINK, X, Y));

	RewriteLinkPtr sc(RewriteLinkCast(hsc));
	Handle result = sc->beta_reduce(HandleMap{}),
		expected = hsc;

	std::cout << "result = " << oc_to_string(result);
	std::cout << "expected = " << oc_to_string(expected);

	TS_ASSERT(content_eq(result, expected));

	logger().info("END TEST: %s", __FUNCTION__);
}

void RewriteLinkUTest::test_consume_quotations_1()
{
	logger().info("BEGIN TEST: %s", __FUNCTION__);

	// Test simple RewriteLink
	Handle
		gpn = createNode(GROUNDED_PREDICATE_NODE, "scm: dummy"),
		gl = createLink(MEET_LINK, X,
		                createLink(QUOTE_LINK,
		                           createLink(EVALUATION_LINK,
		                                      createLink(UNQUOTE_LINK, gpn),
		                                      createLink(UNQUOTE_LINK, X))));

	// Remove the UnquoteLink wrapping gpn as it is useless, and even
	// harmful to the pattern matcher as it makes it believe that the
	// gpn is evaluatable
	RewriteLinkPtr sc(RewriteLinkCast(gl));
	Handle result = sc->consume_quotations(),
		expected = createLink(MEET_LINK, X,
		                      createLink(QUOTE_LINK,
		                                 createLink(EVALUATION_LINK, gpn,
		                                            createLink(UNQUOTE_LINK, X))));

	std::cout << "result = " << oc_to_string(result);
	std::cout << "expected = " << oc_to_string(expected);

	TS_ASSERT(content_eq(result, expected));
}

void RewriteLinkUTest::test_consume_quotations_2()
{
	logger().info("BEGIN TEST: %s", __FUNCTION__);

	std::string rs = _eval->eval("(load-from-path \"tests/atoms/scope/quotations.scm\")");
	logger().debug() << "rs = " << rs;

	// Test simple RewriteLink
	Handle vardecl = _eval->eval_h("vardecl"),
		ill_quoted = _eval->eval_h("ill-quoted");

	// Remove the UnquoteLink wrapping gpn as it is useless, and even
	// harmful to the pattern matcher as it makes it believe that the
	// gpn is evaluatable
	Variables vars(vardecl);
	bool needless_quotation = true;
	Handle result = RewriteLink::consume_quotations(vars, ill_quoted,
	                Quotation(), needless_quotation, false);
	Handle expected = _eval->eval_h("well-quoted");

	std::cout << "result = " << oc_to_string(result);
	std::cout << "expected = " << oc_to_string(expected);

	TS_ASSERT(content_eq(result, expected));
}

void RewriteLinkUTest::test_consume_quotations_3()
{
	logger().info("BEGIN TEST: %s", __FUNCTION__);

	std::string rs = _eval->eval("(load-from-path \"tests/atoms/scope/quotations.scm\")");
	logger().debug() << "rs = " << rs;

	// Test simple RewriteLink
	Handle vardecl = al(VARIABLE_LIST),
		quoted_clauses = _eval->eval_h("quoted-clauses");

	// Remove the UnquoteLink wrapping gpn as it is useless, and even
	// harmful to the pattern matcher as it makes it believe that the
	// gpn is evaluatable
	Variables vars(vardecl);
	bool needless_quotation = true;
	Handle result = RewriteLink::consume_quotations(vars, quoted_clauses,
	               Quotation(), needless_quotation, true);
	Handle expected = _eval->eval_h("consumed-quoted-clauses");

	std::cout << "result = " << oc_to_string(result);
	std::cout << "expected = " << oc_to_string(expected);

	TS_ASSERT(content_eq(result, expected));
}

void RewriteLinkUTest::test_consume_quotations_4()
{
	logger().info("BEGIN TEST: %s", __FUNCTION__);

	std::string rs = _eval->eval("(load-from-path \"tests/atoms/scope/quotations.scm\")");
	logger().debug() << "rs = " << rs;

	// Test simple RewriteLink
	Handle vardecl = al(VARIABLE_LIST),
		quoted_clauses = _eval->eval_h("quoted-grounded-predicate-argument");

	// Remove the UnquoteLink wrapping gpn as it is useless, and even
	// harmful to the pattern matcher as it makes it believe that the
	// gpn is evaluatable
	Variables vars(vardecl);
	bool needless_quotation = true;
	Handle result = RewriteLink::consume_quotations(vardecl, quoted_clauses,
	                Quotation(), needless_quotation, true);
	Handle expected = _eval->eval_h("consumed-quoted-grounded-predicate-argument");

	std::cout << "result = " << oc_to_string(result);
	std::cout << "expected = " << oc_to_string(expected);

	TS_ASSERT(content_eq(result, expected));
}

void RewriteLinkUTest::test_consume_quotations_5()
{
	logger().info("BEGIN TEST: %s", __FUNCTION__);

	std::string rs = _eval->eval("(load-from-path \"tests/atoms/scope/quotations.scm\")");
	logger().debug() << "rs = " << rs;

	// Test simple RewriteLink
	Handle vardecl = al(VARIABLE_LIST),
		quoted_clause = _eval->eval_h("quoted-not-X");

	// LocalQuoteLink should not be removed because NotLink is
	// interpreted as a logical connector by the pattern matcher in
	// that context.
	Variables vars(vardecl);
	bool needless_quotation = true;
	Handle result = RewriteLink::consume_quotations(vars, quoted_clause,
	                Quotation(), needless_quotation, true);
	Handle expected = quoted_clause;

	std::cout << "result = " << oc_to_string(result);
	std::cout << "expected = " << oc_to_string(expected);

	TS_ASSERT(content_eq(result, expected));
}

#undef al
#undef an