OverviewFilesCommitsIssuesDocsReleasesPeers

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

173 lines · cxxtest ref:
/*
 * tests/atoms/BetaReduceUTest.cxxtest
 *
 * Copyright (C) 2016 Linas Vepstas
 * 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/atoms/base/Atom.h>
#include <opencog/atomspace/AtomSpace.h>
#include <opencog/atoms/scope/ScopeLink.h>

using namespace opencog;

// Test the BetaReduce.
//
class BetaReduceUTest :  public CxxTest::TestSuite
{
private:
	AtomSpace _as;

public:
	BetaReduceUTest()
	{
		logger().set_print_to_stdout_flag(true);
	}

	void setUp() {}

	void tearDown() {}

	void test_unquote();
	void test_alpha_hiding();
};

#define N _as.add_node
#define L _as.add_link


// Test beta reduction involving quasi-quotes.
void BetaReduceUTest::test_unquote()
{
	logger().info("BEGIN TEST: %s", __FUNCTION__);

	// Create ScopeLink.
	Handle body =
		L(SET_LINK,
			N(VARIABLE_NODE, "$X"),
			L(QUOTE_LINK, N(VARIABLE_NODE, "$X")),
			L(QUOTE_LINK,
				L(SET_LINK,
					N(VARIABLE_NODE, "$X"),
					L(UNQUOTE_LINK, N(VARIABLE_NODE, "$X")))));

	Handle hscox =
		L(SCOPE_LINK, N(VARIABLE_NODE, "$X"), body);

	ScopeLinkPtr scox(ScopeLinkCast(hscox));
	TS_ASSERT(scox != nullptr);

	// Create a value to plug in;
	Handle smothers_brothers = N(CONCEPT_NODE, "hippy chick");
	HandleSeq vals;
	vals.push_back(smothers_brothers);

	// Perform beta reduction
	const Variables& vars = scox->get_variables();
	Handle redox = vars.substitute(body, vals);
	TS_ASSERT(nullptr != redox);

	redox = _as.add_atom(redox);
	printf("reduced set=%s\n", redox->to_string().c_str());

	// This is the answer we expect to get:
	Handle oxy =
		L(SET_LINK,
			smothers_brothers,
			L(QUOTE_LINK, N(VARIABLE_NODE, "$X")),
			L(QUOTE_LINK,
				L(SET_LINK,
					N(VARIABLE_NODE, "$X"),
					L(UNQUOTE_LINK, smothers_brothers))));

	printf("expected set=%s\n", oxy->to_string().c_str());

	// the reduced and the expected sets should be identical.
	TS_ASSERT(redox == oxy);

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

// Test beta reduction involving colliding variable names.
void BetaReduceUTest::test_alpha_hiding()
{
	logger().info("BEGIN TEST: %s", __FUNCTION__);

	// Create ScopeLink with one variable.
	Handle xbody =
		L(SET_LINK,
			N(VARIABLE_NODE, "$X"),
			L(QUOTE_LINK, N(VARIABLE_NODE, "$X")),
			L(QUOTE_LINK,
				L(SET_LINK,
					N(VARIABLE_NODE, "$X"),
					L(UNQUOTE_LINK, N(VARIABLE_NODE, "$X")))));

	Handle hscox =
		L(SCOPE_LINK, N(VARIABLE_NODE, "$X"), xbody);

	// A scope link with two variables, and $X is clobbered/hidden
	// aka alpha-conversion-conflicted by the inner ScopeLink.
	Handle xybody =
		L(SET_LINK,
			N(VARIABLE_NODE, "$X"),
			N(VARIABLE_NODE, "$Y"),
			L(QUOTE_LINK, N(VARIABLE_NODE, "$X")),
			L(QUOTE_LINK, N(VARIABLE_NODE, "$Y")),
			hscox);

	Handle hscoxy =
		L(SCOPE_LINK,
			L(VARIABLE_LIST,
				N(VARIABLE_NODE, "$X"),
				N(VARIABLE_NODE, "$Y")),
			xybody);

	ScopeLinkPtr scoxy(ScopeLinkCast(hscoxy));
	TS_ASSERT(scoxy != nullptr);

	// Create values to plug in;
	Handle chick = N(CONCEPT_NODE, "hippy chick");
	Handle dude = N(CONCEPT_NODE, "smelly dude");
	HandleSeq vals;
	vals.push_back(chick);
	vals.push_back(dude);

	// Perform beta reduction
	const Variables& vars = scoxy->get_variables();
	Handle redox = vars.substitute(xybody, vals);
	redox = _as.add_atom(redox);
	TS_ASSERT(nullptr != redox);

	printf("reduced set=%s\n", redox->to_string().c_str());

	// What we expect to get.
	Handle xypect =
		L(SET_LINK, chick, dude,
			L(QUOTE_LINK, N(VARIABLE_NODE, "$X")),
			L(QUOTE_LINK, N(VARIABLE_NODE, "$Y")),
			hscox);

	printf("expected set=%s\n", xypect->to_string().c_str());

	// the reduced and the expected sets should be identical.
	TS_ASSERT(redox == xypect);

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