OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-ure / tests / ure / backwardchainer / GradientUTest.cxxtest

247 lines · cxxtest ref:
/*
 * GradientUTest.cxxtest
 *
 * Copyright (C) 2018 Singularity Foundation
 *
 * Authors: Alexey Potapov
 *          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/util/mt19937ar.h>

#include <opencog/atomspace/AtomSpace.h>
#include <opencog/atoms/grounded/LibraryManager.h>
#include <opencog/atoms/truthvalue/SimpleTruthValue.h>
#include <opencog/ure/backwardchainer/BackwardChainer.h>
#include <opencog/ure/URELogger.h>

#include <cxxtest/TestSuite.h>

using namespace std;
using namespace opencog;

#define L _as->add_link
#define N _as->add_node

Handle* id1(AtomSpace* as, Handle* params)
{
	if((*params)->get_type() != LIST_LINK) return params;
	return new Handle((*params)->getOutgoingAtom(0));
}

class GradientUTest: public CxxTest::TestSuite
{
private:
	AtomSpacePtr _as;

	// Constants
	Handle Gradient, ExpandTo, Plus, NumberT, rbs, GradientSum, GradientAny;

	// Number nodes
	Handle N0, N3, N4;

	// Variables
	Handle X, F0, F1, F2, EGY, EGX;

	void set_grounded_schemata();
	void set_constants();
	void set_variables();
	void set_rule1();
	void set_rule2();
	void set_rbs();

public:
	GradientUTest();

	void setUp();
	void tearDown();

	void test_gradient();
};

GradientUTest::GradientUTest()
{
	logger().set_level(Logger::DEBUG);
	logger().set_timestamp_flag(false);
	// logger().set_sync_flag(true);
	logger().set_print_to_stdout_flag(true);
	ure_logger().set_level(Logger::DEBUG);
	// ure_logger().set_timestamp_flag(false);
	// ure_logger().set_sync_flag(true);
	// ure_logger().set_print_to_stdout_flag(true);
	randGen().seed(0);

	_as = createAtomSpace();
	set_grounded_schemata();
	set_constants();
	set_variables();
	set_rule1();
	set_rule2();
	set_rbs();
}

void GradientUTest::set_grounded_schemata()
{
	setLocalSchema("id2", id1);
	setLocalSchema("id4", id1);
}

void GradientUTest::set_constants()
{
	Gradient = N(CONCEPT_NODE, "Gradient");
	ExpandTo = N(PREDICATE_NODE, "ExpandTo");
	Plus = N(CONCEPT_NODE, "+");
	NumberT = N(TYPE_NODE, "NumberNode");
	rbs = N(CONCEPT_NODE, "my-rule-base");
	GradientSum = N(DEFINED_SCHEMA_NODE, "GradientSum");
	GradientAny = N(DEFINED_SCHEMA_NODE, "GradientAny");

	N0 = N(NUMBER_NODE, "0");
	N3 = N(NUMBER_NODE, "3");
	N4 = N(NUMBER_NODE, "4");
}

void GradientUTest::set_variables()
{
	X = N(VARIABLE_NODE, "$X");
	F0 = N(VARIABLE_NODE, "$F0");
	F1 = N(VARIABLE_NODE, "$F1");
	F2 = N(VARIABLE_NODE, "$F2");
	EGX = N(VARIABLE_NODE, "$EGX");
	EGY = N(VARIABLE_NODE, "$EGY");
}

void GradientUTest::set_rule1()
{
	Handle premise1 =
		L(EVALUATION_LINK,
			ExpandTo,
			L(LIST_LINK,
				L(NUMERIC_OUTPUT_LINK, Gradient, F1),
				EGX));
	Handle premise2 =
		L(EVALUATION_LINK,
			ExpandTo,
			L(LIST_LINK,
				L(NUMERIC_OUTPUT_LINK, Gradient, F2),
				EGY));

	L(DEFINE_LINK,
		GradientSum,
     	L(BIND_LINK,
      		L(VARIABLE_LIST,
       			F1,
       			F2,
       			EGX,
					EGY),
      		L(AND_LINK,
					premise1,
					premise2),
				L(EXECUTION_OUTPUT_LINK,
					N(GROUNDED_SCHEMA_NODE, "lib:id4"),
       			L(LIST_LINK,
        				L(EVALUATION_LINK,
         				ExpandTo,
         				L(LIST_LINK,
          					L(NUMERIC_OUTPUT_LINK,
									Gradient,
									L(NUMERIC_OUTPUT_LINK, Plus, F1, F2)),
								L(NUMERIC_OUTPUT_LINK, Plus, EGX, EGY))),
						premise1, premise2))));
}

void GradientUTest::set_rule2()
{
	Handle GradF0 = L(NUMERIC_OUTPUT_LINK, Gradient, F0);

	L(DEFINE_LINK,
		GradientAny,
		L(BIND_LINK,
			L(TYPED_VARIABLE_LINK, F0, NumberT),
			F0,
			L(EXECUTION_OUTPUT_LINK,
				N(GROUNDED_SCHEMA_NODE, "lib:id2"),
				L(LIST_LINK,
					L(EVALUATION_LINK,
						ExpandTo,
						L(LIST_LINK, GradF0, N0))))));
}

void GradientUTest::set_rbs()
{
	// Assign GradientSum and its weight to rbs
	TruthValuePtr stv = SimpleTruthValue::createTV(0.4, 1.0);
	Handle GSM = L(MEMBER_LINK, GradientSum, rbs);
	GSM->setValue(truth_key(), stv);

	// Assign GradientAny and its weight to rbs
	Handle GAM = L(MEMBER_LINK, GradientAny, rbs);
	GAM->setValue(truth_key(), stv);
}

void GradientUTest::setUp()
{
}

void GradientUTest::tearDown()
{
	_as->clear();
}

void GradientUTest::test_gradient()
{
	logger().debug("BEGIN TEST: %s", __FUNCTION__);

	Handle src2 =
		L(EVALUATION_LINK,
			ExpandTo,
			L(LIST_LINK,
					L(NUMERIC_OUTPUT_LINK,
						Gradient,
						L(NUMERIC_OUTPUT_LINK, Plus, N4, N3)),
					X));

	BackwardChainer bc(*_as.get(), rbs, src2);
	bc.get_config().set_maximum_iterations(10);
	bc.do_chain();
	Handle result = bc.get_results(),
		expected = L(SET_LINK,
		             L(EVALUATION_LINK,
		               N(PREDICATE_NODE, "ExpandTo"),
		               L(LIST_LINK,
		                 L(NUMERIC_OUTPUT_LINK,
		                   N(CONCEPT_NODE, "Gradient"),
		                   L(NUMERIC_OUTPUT_LINK,
		                     N(CONCEPT_NODE, "+"),
		                     N(NUMBER_NODE, "4"),
		                     N(NUMBER_NODE, "3"))),
		                 L(NUMERIC_OUTPUT_LINK,
		                   N(CONCEPT_NODE, "+"),
		                   N(NUMBER_NODE, "0"),
		                   N(NUMBER_NODE, "0")))));

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

	TS_ASSERT_EQUALS(result, expected);

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

#undef L
#undef N