/*
* Created on Nov 21, 2006 Copyright (C) 2001-6, Anthony Harrison anh23@pitt.edu
* (jactr.org) This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of the License,
* or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have
* received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.jactr.core.module.declarative;
import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.Future;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jactr.core.chunk.IChunk;
import org.jactr.core.chunktype.IChunkType;
import org.jactr.core.module.ModuleTest;
import org.jactr.core.module.declarative.search.filter.AcceptAllFilter;
import org.jactr.core.module.declarative.search.filter.PartialMatchActivationFilter;
import org.jactr.core.production.request.ChunkTypeRequest;
import org.jactr.core.slot.BasicSlot;
import org.jactr.core.slot.DefaultConditionalSlot;
import org.jactr.core.slot.IConditionalSlot;
public class DeclarativeModuleTest extends ModuleTest
{
/**
* logger definition
*/
static private final Log LOGGER = LogFactory
.getLog(DeclarativeModuleTest.class);
/**
* test chunktype creation and addition as well as parenting
*
* @throws Exception
*/
public void testChunkTypes() throws Exception
{
IDeclarativeModule dm = getModel().getDeclarativeModule();
assertNotNull(dm);
int existing = dm.getChunkTypes().get().size();
/*
* lets create a chunk type
*/
IChunkType testType = createChunkType(dm, "test", null, "a", "b", "c");
assertNotNull(testType);
/*
* and add it..
*/
Future<IChunkType> added = dm.addChunkType(testType);
assertNotNull(added);
testType = added.get();
assertNotNull(testType);
/*
* the model should have one chunktype
*/
added = dm.getChunkType("test");
assertNotNull(added);
assertEquals(testType, added.get());
assertEquals(existing + 1, dm.getChunkTypes().get().size());
assertEquals(3, testType.getSymbolicChunkType().getSlots().size());
/*
* lets create a new chunk type
*/
IChunkType secondType = createChunkType(dm, "test2", testType, "d");
assertNotNull(secondType);
added = dm.addChunkType(secondType);
assertNotNull(added);
secondType = added.get();
assertNotNull(secondType);
added = dm.getChunkType("test2");
assertNotNull(added);
assertEquals(secondType, added.get());
assertEquals(existing + 2, dm.getChunkTypes().get().size());
assertEquals(4, secondType.getSymbolicChunkType().getSlots().size());
assertTrue(secondType.isA(testType));
assertFalse(testType.isA(secondType));
}
/**
* test chunk creation, addition, & merging
*/
public void testChunks() throws Exception
{
IDeclarativeModule dm = getModel().getDeclarativeModule();
assertNotNull(dm);
/*
* first we need a chunktype
*/
IChunkType rootType = createChunkType(dm, "test", null, "a", "b", "c");
rootType = dm.addChunkType(rootType).get();
assertNotNull(rootType);
/*
* now lets create a chunk
*/
IChunk firstChunk = createChunk(dm, "one", rootType, "a", 1, "b", 2, "c", 3);
assertNotNull(firstChunk);
assertEquals(0, rootType.getSymbolicChunkType().getChunks().size());
firstChunk = dm.addChunk(firstChunk).get();
assertEquals(1, rootType.getSymbolicChunkType().getChunks().size());
assertEquals(firstChunk, dm.getChunk("one").get());
/*
* now lets create a chunk that will be merged
*/
IChunk mergie = createChunk(dm, "mergie", rootType, "a", 1, "b", 2, "c", 3);
assertNotNull(mergie);
assertNotSame(mergie, firstChunk);
IChunk newMergie = dm.addChunk(mergie).get();
// the same contents
assertEquals(mergie, firstChunk);
// new and old handles
assertTrue(newMergie == firstChunk);
assertFalse(mergie == firstChunk);
// no record of the name
assertNull(dm.getChunk("mergie").get());
assertEquals(1, rootType.getSymbolicChunkType().getChunks().size());
}
/**
* test exact match searching. searching using strings, numbers, boolean, and
* chunks
*
* @throws Exception
*/
public void testExactMatch() throws Exception
{
IDeclarativeModule dm = getModel().getDeclarativeModule();
assertNotNull(dm);
/*
* first we need some chunktypes
*/
IChunkType test1 = createChunkType(dm, "test1", null, "a", "b", "c");
test1 = dm.addChunkType(test1).get();
assertNotNull(test1);
IChunkType test2 = createChunkType(dm, "test2", test1, "d");
test2 = dm.addChunkType(test2).get();
assertNotNull(test2);
IChunk t11 = dm.addChunk(
createChunk(dm, "t11", test1, "a", 1, "b", "bee", "c", false)).get();
IChunk t12 = dm.addChunk(
createChunk(dm, "t12", test1, "a", 4, "b", t11, "c", true)).get();
IChunk t13 = dm.addChunk(
createChunk(dm, "t13", test1, "a", 0, "b", t11, "c", t12)).get();
dm.addChunk(
createChunk(dm, "t21", test2, "a", 1, "b", "bee", "c", false, "d", t13))
.get();
assertEquals(1, test1.getSymbolicChunkType().getChildren().size());
assertEquals(4, test1.getSymbolicChunkType().getChunks().size());
assertEquals(1, test2.getSymbolicChunkType().getChunks().size());
ChunkTypeRequest pattern = new ChunkTypeRequest(test1,
Arrays.asList(new IConditionalSlot[] { new DefaultConditionalSlot("a",
IConditionalSlot.LESS_THAN, 4) }));
assertEquals(3, dm.findExactMatches(pattern, null, new AcceptAllFilter())
.get().size());
pattern = new ChunkTypeRequest(test1, Arrays.asList(new IConditionalSlot[] {
new DefaultConditionalSlot("a", IConditionalSlot.LESS_THAN, 4),
new DefaultConditionalSlot("c", IConditionalSlot.NOT_EQUALS, false) }));
assertEquals(1, dm.findExactMatches(pattern, null, new AcceptAllFilter())
.get().size());
pattern = new ChunkTypeRequest(test2, Arrays.asList(new IConditionalSlot[] {
new DefaultConditionalSlot("a", 1),
new DefaultConditionalSlot("b", "bee") }));
assertEquals(1, dm.findExactMatches(pattern, null, new AcceptAllFilter())
.get().size());
pattern = new ChunkTypeRequest(test1, Arrays.asList(new IConditionalSlot[] {
new DefaultConditionalSlot("a", 1),
new DefaultConditionalSlot("b", "bee") }));
assertEquals(2, dm.findExactMatches(pattern, null, new AcceptAllFilter())
.get().size());
}
/**
* test partial match searching. searching using strings, numbers, boolean,
* and chunks
*
* @throws Exception
*/
public void testPartialMatch() throws Exception
{
IDeclarativeModule dm = getModel().getDeclarativeModule();
assertNotNull(dm);
/*
* first we need some chunktypes
*/
IChunkType test1 = createChunkType(dm, "test1", null, "a", "b", "c");
test1 = dm.addChunkType(test1).get();
assertNotNull(test1);
IChunkType test2 = createChunkType(dm, "test2", test1, "d");
test2 = dm.addChunkType(test2).get();
assertNotNull(test2);
IChunk t11 = dm.addChunk(
createChunk(dm, "t11", test1, "a", 1, "b", "bee", "c", false)).get();
IChunk t12 = dm.addChunk(
createChunk(dm, "t12", test1, "a", 4, "b", t11, "c", true)).get();
IChunk t13 = dm.addChunk(
createChunk(dm, "t13", test1, "a", 0, "b", t11, "c", t12)).get();
dm.addChunk(
createChunk(dm, "t21", test2, "a", 1, "b", "bee", "c", false, "d", t13))
.get();
assertEquals(1, test1.getSymbolicChunkType().getChildren().size());
assertEquals(4, test1.getSymbolicChunkType().getChunks().size());
assertEquals(1, test2.getSymbolicChunkType().getChunks().size());
ChunkTypeRequest pattern = new ChunkTypeRequest(test1,
Arrays.asList(new IConditionalSlot[] { new DefaultConditionalSlot("a",
IConditionalSlot.LESS_THAN, 4) }));
// chunk filter for partial matching is important as it verifies that at
// least one feature matches.
Collection<IChunk> results = dm.findPartialMatches(pattern, null,
new PartialMatchActivationFilter(pattern, Double.NEGATIVE_INFINITY))
.get();
assertEquals(3, results.size());
pattern = new ChunkTypeRequest(test1, Arrays.asList(new IConditionalSlot[] {
new DefaultConditionalSlot("a", IConditionalSlot.LESS_THAN, 4),
new DefaultConditionalSlot("c", IConditionalSlot.NOT_EQUALS, true) }));
assertEquals(
3,
dm.findPartialMatches(pattern, null,
new PartialMatchActivationFilter(pattern, Double.NEGATIVE_INFINITY))
.get()
.size());
pattern = new ChunkTypeRequest(test2, Arrays.asList(new IConditionalSlot[] {
new DefaultConditionalSlot("a", 1),
new DefaultConditionalSlot("b", "bee") }));
assertEquals(
1,
dm.findPartialMatches(pattern, null,
new PartialMatchActivationFilter(pattern, Double.NEGATIVE_INFINITY))
.get().size());
pattern = new ChunkTypeRequest(test1, Arrays.asList(new IConditionalSlot[] {
new DefaultConditionalSlot("a", 1),
new DefaultConditionalSlot("b", "bee") }));
assertEquals(
2,
dm.findPartialMatches(pattern, null,
new PartialMatchActivationFilter(pattern, Double.NEGATIVE_INFINITY))
.get().size());
}
static public IChunk createChunk(IDeclarativeModule module, String name,
IChunkType type, Object... slotsAndValues) throws Exception
{
Future<IChunk> futureChunk = module.createChunk(type, name);
assertNotNull(futureChunk);
IChunk chunk = futureChunk.get();
assertNotNull(chunk);
assertTrue(chunk.isA(type));
/*
* set the slot values..
*/
for (int i = 0; i < slotsAndValues.length; i += 2)
{
BasicSlot slot = new BasicSlot(slotsAndValues[i].toString(),
slotsAndValues[i + 1]);
chunk.getSymbolicChunk().addSlot(slot);
}
return chunk;
}
static public IChunkType createChunkType(IDeclarativeModule module,
String name, IChunkType parent, String... slots) throws Exception
{
Future<IChunkType> chunkType = module.createChunkType(parent, name);
assertNotNull(chunkType);
IChunkType actualChunkType = chunkType.get();
assertNotNull(actualChunkType);
for (String slotName : slots)
actualChunkType.getSymbolicChunkType().addSlot(new BasicSlot(slotName));
return actualChunkType;
}
}