OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-atomspace / tests / query / TypeChoiceUTest.cxxtest

259 lines · cxxtest ref:
/*
 * tests/query/TypeChoiceUTest.cxxtest
 *
 * Copyright (C) 2015 OpenCog Foundation
 * All Rights Reserved
 *
 * Author: 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/atomspace/AtomSpace.h>
#include <opencog/util/Logger.h>
#include <cxxtest/TestSuite.h>

using namespace opencog;

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

class TypeChoiceUTest: public CxxTest::TestSuite
{
private:
	AtomSpacePtr as;
	Handle X, Y, Z, type_choice_decl,
		connected_pattern, disconnected_pattern,
		predicate, lambda, implication;

public:
	TypeChoiceUTest(void)
	{
		logger().set_level(Logger::DEBUG);
		logger().set_print_to_stdout_flag(true);
		as = createAtomSpace();
	}

	~TypeChoiceUTest()
	{
		// Erase the log file if no assertions failed.
		if (!CxxTest::TestTracker::tracker().suiteFailed())
			std::remove(logger().get_filename().c_str());
	}

	void setUp(void);
	void tearDown(void);

	void test_connected();
	void test_disconnected();
	void test_forall();
};

void TypeChoiceUTest::tearDown(void)
{
	as->clear();
}

void TypeChoiceUTest::setUp(void)
{
	X = an(VARIABLE_NODE, "$X");
	Y = an(VARIABLE_NODE, "$Y");
	Z = an(VARIABLE_NODE, "$Z");

	type_choice_decl =
		al(VARIABLE_LIST,
		   al(TYPED_VARIABLE_LINK,
		      X,
		      al(TYPE_CHOICE,
		         an(TYPE_NODE, "PredicateNode"),
		         an(TYPE_NODE, "LambdaLink"))),
		   al(TYPED_VARIABLE_LINK,
		      Y,
		      al(TYPE_CHOICE,
		         an(TYPE_NODE, "PredicateNode"),
		         an(TYPE_NODE, "LambdaLink"))));

	connected_pattern =
		al(COLLECTION_OF_LINK, {al(MEET_LINK,
		   type_choice_decl,
		   al(IMPLICATION_LINK, X, Y))});

	// Exclude internal marker atoms from matching
	Handle marker = an(PREDICATE_NODE, "*-IsKeyFlag-*");
	disconnected_pattern =
		al(COLLECTION_OF_LINK, {al(MEET_LINK,
		   type_choice_decl,
		   al(AND_LINK,
		      X, Y,
		      al(NOT_LINK, al(EQUAL_LINK, X, marker)),
		      al(NOT_LINK, al(EQUAL_LINK, Y, marker))))});

	predicate = an(PREDICATE_NODE, "P");

	lambda =
		al(LAMBDA_LINK,
		   X,
		   al(EVALUATION_LINK,
		      an(PREDICATE_NODE, "P"),
		      X));

	implication =
		al(IMPLICATION_LINK,
		   predicate,
		   lambda);
}

/*
 * TypeChoice over a connected component
 */
void TypeChoiceUTest::test_connected()
{
	logger().debug("BEGIN TEST: %s", __FUNCTION__);

	Handle result = HandleCast(connected_pattern->execute(as.get()));
	Handle expected = al(SET_LINK, al(LIST_LINK, predicate, lambda));

	logger().debug() << "result = " << result->to_string();
	logger().debug() << "expected = " << expected->to_string();
    
	TS_ASSERT_EQUALS(result, expected);
}

/*
 * TypeChoice over disconnected components
 */
void TypeChoiceUTest::test_disconnected()
{
	logger().debug("BEGIN TEST: %s", __FUNCTION__);

	Handle result = HandleCast(disconnected_pattern->execute(as.get()));
	Handle expected = al(SET_LINK,
	                     al(LIST_LINK, lambda, predicate),
	                     al(LIST_LINK, predicate, predicate),
	                     al(LIST_LINK, lambda, lambda),
	                     al(LIST_LINK, predicate, lambda));

	logger().debug() << "result = " << result->to_string();
	logger().debug() << "expected = " << expected->to_string();
	
	TS_ASSERT_EQUALS(result, expected);
}

/*
 * TypeChoice over a Lambda pattern. Specifically
 *
 * (define forall-instantiation-vardecl
 *  (VariableList
 *      (TypedVariableLink
 *         (VariableNode "$TyVs")
 *         (TypeChoice
 *            (TypeNode "TypedVariableLink")
 *            (TypeNode "VariableList")))
 *      (VariableNode "$B")))
 *
 * (define forall-instantiation-body
 *   (QuoteLink
 *      (LambdaLink
 *         (UnquoteLink (VariableNode "$TyVs"))
 *         (UnquoteLink (VariableNode "$B"))))
 *
 * (define forall-instantiation-get
 *   (Meet
 *      forall-instantiation-vardecl
 *      forall-instantiation-body))
 *
 * Over
 *
 * (define forall-candidate
 *   (LambdaLink
 *      (VariableList
 *         (TypedVariableLink
 *            (VariableNode "$X")
 *            (TypeNode "ConceptNode"))
 *         (TypedVariableLink
 *            (VariableNode "$Y")
 *            (TypeNode "PredicateNode")))
 *      (EvaluationLink
 *         (PredicateNode "are-concept-and-predicate")
 *         (ListLink
 *            (VariableNode "$X")
 *            (VariableNode "$Y")))))
 *
 * With result
 *
 * TyVs =
 *      (VariableList
 *         (TypedVariableLink
 *            (VariableNode "$X")
 *            (TypeNode "ConceptNode"))
 *         (TypedVariableLink
 *            (VariableNode "$Y")
 *            (TypeNode "PredicateNode")))
 *
 * B =
 *      (EvaluationLink
 *         (PredicateNode "are-concept-and-predicate")
 *         (ListLink
 *            (VariableNode "$X")
 *            (VariableNode "$Y")))
 */
void TypeChoiceUTest::test_forall()
{
	logger().debug("BEGIN TEST: %s", __FUNCTION__);

	Handle TyVs = an(VARIABLE_NODE, "$TyVs"),
		TVLT = an(TYPE_NODE, "TypedVariableLink"),
		VLT = an(TYPE_NODE, "VariableList"),
		TyVs_vardecl = al(TYPED_VARIABLE_LINK, TyVs, al(TYPE_CHOICE, TVLT, VLT)),
		B = an(VARIABLE_NODE, "$B"),
		forall_instantiation_vardecl = al(VARIABLE_LIST, TyVs_vardecl, B),
		forall_instantiation_body = al(QUOTE_LINK,
		                               al(LAMBDA_LINK,
		                                  al(UNQUOTE_LINK, TyVs),
		                                  al(UNQUOTE_LINK, B))),
		forall_instantiation_get = al(COLLECTION_OF_LINK, {al(MEET_LINK,
		                              forall_instantiation_vardecl,
		                              forall_instantiation_body)}),
		X = an(VARIABLE_NODE, "$X"),
		CT = an(TYPE_NODE, "ConceptNode"),
		X_vardecl = al(TYPED_VARIABLE_LINK, X, CT),
		Y = an(VARIABLE_NODE, "$Y"),
		PT = an(TYPE_NODE, "PredicateNode"),
		Y_vardecl = al(TYPED_VARIABLE_LINK, Y, PT),
		forall_candidate_vardecl = al(VARIABLE_LIST, X_vardecl, Y_vardecl),
		CNP = an(PREDICATE_NODE, "are-concept-and-predicate"),
		forall_candidate_body = al(EVALUATION_LINK, CNP, al(LIST_LINK, X, Y)),
		forall_candidate = al(LAMBDA_LINK,
		                      forall_candidate_vardecl,
		                      forall_candidate_body);

	Handle result = HandleCast(forall_instantiation_get->execute(as.get()));
	Handle expected = al(SET_LINK,
	                     al(LIST_LINK,
	                        forall_candidate_vardecl,
	                        forall_candidate_body));

	logger().debug() << "candidate = " << forall_candidate->to_string();
	logger().debug() << "query = " << forall_instantiation_get->to_string();
	logger().debug() << "result = " << result->to_string();
	logger().debug() << "expected = " << expected->to_string();

	TS_ASSERT_EQUALS(result, expected);
}

#undef al
#undef an