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