/*
* 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