You are here

Benefits of jACT-R

What is the added value of a Java implementation when the canonical Lisp works just fine? There are quite a few benefits, some due to language specific affordances and others due to the design that Java supports.

Loose Module Coupling

All of jACT-R is coded to Java interfaces. This allows one to swap out implementations with little pain. But there are also various levels of interfaces based on ACT-R versions. Because of the loose coupling, the modeler is generally free to mix and match modules with little concern for negative interactions. If you want to use the old PG-C production learning, just use org.jactr.core.modules.procedural.five.DefaultProceduralModule5 and its associated learning module instead of DefaultProceduralModule6*.

There is no need to ever modify the architecture code to use (or build and integrate) a particular module.

The loose coupling provides an additional benefit: if you don't need a module, it effectively doesn't exist. There is no need to check enablement flags, the code simply isn't loaded into the model. Want to run two models concurrently comparing PG-C versus reinforcement learning? No problem, just load each model with a different procedural module.

Less Restrictive Time Assumptions

Canonical ACT-R assumes it has total control over the flow of time. jACT-R makes no such assumptions. There are numerous different types of clocks that can be used, but common to them all is that anyone using the same clock with be bound to the same time. There are shared clocks which only advance time when all participants (models and/or simulations), private clocks which are only updated by one participant (i.e. Unreal would own the clock in USARsim).

Because of the lack of total control of the clock, all the modules and events are aware of the possibility that they may fire (a little) late.

Variable Threading Model

At this point in time thread support in the various Lisp flavors is, at best, incomplete. Allegro does have native threads, but it uses heap level locking so only one thread can run at any given time. SBCL is able to run multiple threads concurrently, but it is not safely reentrant.

Java supports native threads with solid concurrency tools across the board. This is used to great extent throughout jACT-R. Most of the modules are coded with the explicit assumption that they will be run on different threads (or even machines). At the most basic level, there is at least one thread per model running (and yes, you can run multiple models in the same environment concurrently). If you use embodiment (i.e. visual, motor, vocal, etc), there will be a separate dedicated thread for processing perceptual information. Additionally, learning modules can be placed onto their own thread to off-load costly learning calculations. Similarly, the declarative and procedural modules can have their own threads enabled, if desired (but the added value is currently limited).

Synchronous or Asynchronous event model

Canonical ACT-R uses function hooks to allow instrumentation. jACT-R uses an event model instead. Models, chunktypes, chunks, productions, buffers and modules all support event notification to registered listeners. These listeners can be synchronous or asynchronous. This provides great flexibility in the processing of events and extending the architecture. For instance: the default declarative module attaches a listener to all the buffers in the model. When the buffer removes a chunk, the declarative module is notified (synchronously) and it then encodes the chunk into memory. The declarative learning module attaches a listener to unencoded chunks and tracks changes to that chunk so that it can correctly update the associative links to and from that chunk.

Synchronous event delivery is used when time is critical, and is typically used in support of theoretical extension. These event handlers need to act fast to minimize performance impact. Asynchronous events are delivered at some point later in time (but in order) and is primarily used for instrumentation, logging, etc. However, most events are fully specified (i.e. include all the information needed to describe what has happened), which means asynchronous events can also be used for theoretical extension, such as enabling delayed learning.

* unfortunately, this is a hypothetical example. While ACT-R 5 PG-C learning is implemented, there is no DefaultProceduralModule5, only 6. However, to enable PG-C you can just extend module6 and replace the createProduction() method to return DefaultProduction5.