Chunks

Chunks are the declarative glue that holds a model together. They are the explicitly inspectable knowledge representation (as opposed to productions). At the architectural level, the declarative module is responsible for their creation, indexing, and management. At the model level, they are created when a new representation is added to a specific buffer and encoded on removal (usually).

Copying

Copying a chunk is frequently needed by buffers that copy on insertion. This is delegated to the IDeclarativeModule. Note: You cannot copy chunks from one model into another. That's a theoretical brain transplant.

 IModel model = ...
 IDeclarativeModule decM = model.getDeclarativeModule();
 IChunk toCopy = ...
 IChunk copied = decM.copyChunk(toCopy).get();

Creating

  IModel model = ...
  IDeclarativeModule decM = model.getDeclarativeModule();
  IChunkType chunkType = ...
  String chunkName = ...
  Future result = decM.createChunk(chunkType, chunkName);
  IChunk newChunk = result.get();

The IDeclarativeModule explicitly supports asynchronous action. That is why all the methods return futures and not the relevant type directly. If you don't care about asynchrony, just call the future's get() method. Otherwise, separate the request from the harvesting to give other threads a chance..

Encoding

 IModel model = ...
 IChunk chunkToEncode = ...
 IDeclarativeModule decM = model.getDeclarativeModule();
 Future result = decM.addChunk(chunkToEncode);
 
 IChunk encoded = result.get();
 
/*
 Merging might mean that the returned chunk is not the exact same reference,
 however, both IChunk objects will point to the same content
*/

 boolean alwaysTrue = encoded.equalsSymbolic(chunkToEncode);

 boolean trueIfNotMerged = encoded == chunkToEncode;

Modifying

Chunks once encoded cannot be modified, only copied (IDeclarativeModule.copyChunk()). However, if it hasn't been encoded, there are two considerations. If you have just created the chunk and no other buffers or modules might have access to it, you can merely manipulate it directly:

 IChunk chunk = ...
 ISymbolicChunk sc = chunk.getSymbolicChunk();
 
 for(ISlot slot : sc.getSlots())
  ((IMutableSlot) slot).setValue(...);

//the same applies for parameters

However, once the chunk is accessible in the system (added to a buffer, referenced by another chunk, etc), you need to be concerned about other threads accessing it. If the chunk is in a buffer, the easiest way to do this is with ChunkUtilities and its associated IChunkModifier interface. The utility class handles the locking and execution time for you.

  IModel model = ...;
  IActivationBuffer goalBuffer = model.getActivationBuffer(IActivationBuffer.GOAL);
  ChunkUtilities.manipulateChunkLater(goalBuffer, new IChunkModifier(){
    public void modify(IChunk chunk, IActivationBuffer buffer)
    {
       ISymbolicChunk sc = chunk.getSymbolicChunk();
       for(ISlot slot : sc.getSlots())
        ((IMutableSlot) slot).setValue(...);
    }
});

Otherwise, you should use the chunk's write lock to ensure no contention.

 IChunk chunk = ...
 Lock lock = chunk.getWriteLock();
 try
 {
   lock.lock();
    ISymbolicChunk sc = chunk.getSymbolicChunk();
       for(ISlot slot : sc.getSlots())
        ((IMutableSlot) slot).setValue(...);
 }
 finally
 {
  lock.unlock();
 }