OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-atomspace / tests / query / LoopPatternUTest.cxxtest

199 lines · cxxtest ref:
/*
 * tests/query/LoopPatternUTest.cxxtest
 *
 * Copyright (C) 2009 Linas Vepstas <linasvepstas@gmail.com>
 * 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/atomspace/AtomSpace.h>
#include <opencog/util/Logger.h>

#include "imply.h"
#undef DEBUG

using namespace opencog;

class LoopPatternUTest :  public CxxTest::TestSuite
{
	private:
		AtomSpacePtr as;

		Handle clauses, implicand;
		Handle hone, htwo, hthree;

	public:

		LoopPatternUTest(void)
		{
			logger().set_level(Logger::DEBUG);
			logger().set_print_to_stdout_flag(true);
		}

		~LoopPatternUTest()
		{
			// 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_prep(void);
		void verify(Handle);
		void cycle(Handle, Handle, Handle);
};

/*
 * This function sets up the following structures:
 */
#define an as->add_node
#define al as->add_link
#define getarity(hand) hand->get_arity()
#define getlink(hand,pos) hand->getOutgoingAtom(pos)

void LoopPatternUTest::tearDown(void)
{
}
void LoopPatternUTest::setUp(void)
{
	as = createAtomSpace();

	// Create an implication link that will be tested.
	clauses =
		al(AND_LINK,
		   al(LIST_LINK,
		      an(VARIABLE_NODE, "$var0"),
		      an(VARIABLE_NODE, "$var1")
		      ),
		   al(LIST_LINK,
		      an(VARIABLE_NODE, "$var1"),
		      an(VARIABLE_NODE, "$var2")
		      ),
		   al(LIST_LINK,
		      an(VARIABLE_NODE, "$var2"),
		      an(VARIABLE_NODE, "$var0")
		      )
		   );
	implicand =
		al(ORDERED_LINK,
		   an(VARIABLE_NODE, "$var0"),
		   an(VARIABLE_NODE, "$var1"),
		   an(VARIABLE_NODE, "$var2")
		   );

	// Create data on which the above pattern should match
	al(LIST_LINK,
		hone = an(CONCEPT_NODE, "one"),
		htwo = an(CONCEPT_NODE, "two")
	);
	al(LIST_LINK,
		htwo = an(CONCEPT_NODE, "two"),
		hthree = an(CONCEPT_NODE, "three")
	);
	al(LIST_LINK,
		hthree = an(CONCEPT_NODE, "three"),
		hone = an(CONCEPT_NODE, "one")
	);
}

/*
 * Circular loop
 *
 * Expect to get the following result, given the above data:
 *
 *    OrderedLink
 *       ConceptNode "one"
 *       ConceptNode "two"
 *       ConceptNode "three"
 */
void LoopPatternUTest::cycle(Handle va, Handle vb, Handle vc)
{
	if (va == hone)
	{
		TSM_ASSERT_EQUALS("incorrect vb", htwo, vb);
		TSM_ASSERT_EQUALS("incorrect vc", hthree, vc);
	}
	else 
	if (va == htwo)
	{
		TSM_ASSERT_EQUALS("incorrect vb", hthree, vb);
		TSM_ASSERT_EQUALS("incorrect vc", hone, vc);
	}
	else 
	if (va == hthree)
	{
		TSM_ASSERT_EQUALS("incorrect vb", hone, vb);
		TSM_ASSERT_EQUALS("incorrect vc", htwo, vc);
	}
	else 
		TSM_ASSERT_EQUALS("invalid va", 0, 1);
}

void LoopPatternUTest::verify(Handle soln)
{
	Handle va = getlink(soln, 0);
	Handle vb = getlink(soln, 1);
	Handle vc = getlink(soln, 2);

	cycle (va, vb, vc);
}

void LoopPatternUTest::test_prep(void)
{
	logger().debug("BEGIN TEST: %s", __FUNCTION__);
 
	// Result should be a ListLink
	Handle result = imply(as, clauses, implicand);

#define NO_SELF_GROUNDING 1
#ifdef NO_SELF_GROUNDING
	// Expect three answers.
	TSM_ASSERT_EQUALS("incorrect arity", getarity(result), 3);
#else
	// Expect five answers.
	TSM_ASSERT_EQUALS("incorrect arity", getarity(result), 5);
#endif

	// Check that each answer gives the loop in cyclic order.
	verify (getlink(result, 0));
	verify (getlink(result, 1));
	verify (getlink(result, 2));

	Handle va = getlink(getlink(result, 0), 0);
	Handle vb = getlink(getlink(result, 1), 0);
	Handle vc = getlink(getlink(result, 2), 0);
	bool found_one = false, found_two = false, found_three = false;
	if (va == hone) found_one = true;
	if (va == htwo) found_two = true;
	if (va == hthree) found_three = true;

	if (vb == hone) found_one = true;
	if (vb == htwo) found_two = true;
	if (vb == hthree) found_three = true;

	if (vc == hone) found_one = true;
	if (vc == htwo) found_two = true;
	if (vc == hthree) found_three = true;

	if (!(found_one && found_two && found_three))
		TSM_ASSERT_EQUALS("not all solutions enumerated", 0, 1);

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