Divergences

Here I list out the general differences between the canonical and the Java implementations of ACT-R. Since jACT-R has been coded largely in isolation from the canonical code, there are many design decision differences.

I am fully committed to theoretical compatibility, but not implementation. In other words, equations and key behaviors are the primary goal (i.e. activation equations and chunk immutability), not consistency in trivial areas (i.e. exact chunk structures, slot names, or visual search priorities). But, I will endeavor to ensure minimal hassle when migrating models from one version to another (i.e. automatic translation/transformation).

Productions

Overwrite action

Canonical ACT-R supports an overwrite buffer operation that performs an end-run around the managing module and also prevents the encoding of previous contents. =goal> =chunk will replace the contents of the goal buffer with =chunk without encoding the current contents.

jACT-R does not directly support this operation. You can set, add, remove, modify or request, and that's it. You cannot circumvent the encoding. The best you can do is use the set operation which will move a chunk from one buffer to another (in 0 time). But the prior contents will still be encoded. The Lisp parser will tranform overwrites into sets automatically and notify you that this has been done.

Explicit state reset

If a retrieval fails, the only way to reset the state is to complete a successful retrieval. There is no mechanism to explicitly reset the state. While some modules do have this (+visual> isa clear), it is not standard. jACT-R solves this by using an explicit remove operation (-retrieval>). If there is nothing in the buffer, it will have its states reset.

Retrieval module

Indexed Retrievals

Retrieval module does permit indexed (i.e. immediate) retrievals of chunks you already have references to. However, this must be explicitly enabled with the EnableIndexedRetrievals parameter.

Asynchrony

Retrievals can also be performed asynchronously if the declarative module is asynchronous.

Declarative FINSTS

Declarative FINSTs are controlled by two parameters: FINSTDurationTime (3 seconds) and NumberOfFINSTs (4 chunks). :recently-retrieved (null, false, true) can be used in retrieval requests.

Partial Matching

The canonical ACT-R partial matching allows completely mismatching chunks to be retrieved, assuming they have the highest activation. jACT-R requires at least one feature in the retrieval spec to match. This is a functional, not theoretic, design decision. This matches better with the modeler's expectations and is also more performant (not requiring testing against all of DM).

Visual System

Coordinate System

Quick, draw a two-dimensional graph. Did you put the x-axis on the bottom, increasing to the right with the y-axis on the left increasing upwards? You sure didn't draw it with y-axis decreasing downwards. Now draw a graph with a nature center point. Yeah, you get the picture.

Canonical Lisp uses a computer screen based coordinate system, +x to the right, +y down. While the slot names are the same (for now), the coordinates in jACT-R are retinotopic visual angles (degrees). 0,0 is at center, +x to the right, +y up.

Recycled Locations

From an informal survey of modelers, I found that almost none of us use the visual-location chunks for anything other than to encode some object. Because of this limited use and the fact that during the lifetime of a model there can be thousands of these chunks created, jACT-R actually recycles visual-locations.

There is at most one visual-location for each possible retinotopic position (as defined by the visual field size and resolution). Its x and y locations are fixed, but the remaining slot values are mutable by the system. The mutable slot values have a relatively limited lifespan. They are valid only after a visual search until the next visual search is started. In this way the explosive growth of visual locations is eliminated, which is particularly important when operating for long periods in a truly embodied environment.

FINSTS

Canonical ACT-R marks FINSTS at the visual-location level. This makes sense assuming that the visual scene is limited. However, if you've got multiple objects at the same location (due to visual resolution issue or overlap), you can easily end up missing objects and can possibly end up in a situation where you can never actually encode some objects.

To prevent this, jACT-R assigns FINSTS at the object level. In simple scenes, the behavior is exactly the same. In more complex scenes (with overlapping objects), this allows the visual system to differentiate between attended and unattended objects at the same location. The semantics are exactly the same for making a visual-location request.

The only incompatibility this introduces is with the visual-location buffer query. Canonical ACT-R supports ?visual-location> attended {t|new|nil}. jACT-R does not support this query at all. I'm looking at implementing it in the future, but it will be based on the attended status of all the objects at that location.

If you require this query, contact me and I'll see about bumping up its priority.

Movement Tolerances

Canonical ACT-R uses movement tolerance to allow the model to encode a visual object after it has moved from the location returned from the visual search. jACT-R uses this tolerance to also deal with object tracking. If the object is moving too fast, it will exceed the tolerance. When this occurs, the track is lost, the visual buffer state is set to error, but the chunk is maintained in the buffer. (I'm still trying to figure out whether it should be removed from the buffer or not)

Object tracking

So if I've attended to an object why do I have to explicitly tell the visual system to follow it? When something you're looking at moves, it's hard not to follow it. In jACT-R all attended objects are automatically tracked. The only benefit of using the object tracking mechanism is that it stuffs the updated visual location of the object into the visual-location buffer.

If the parameter EnableStickyAttention is true, attended objects will remain attended as long as the object is in the visual field. No amount of movement will shake it.

Asynchrony

All perceptual/motor modules are already asynchronous.

Motor System

There is no manual system, just a global motor system. The motor system is a drop-in replacement with the same basic functionality, plus a few bells and whistles.

Muscle-level parallelism

If EnableMuscleLevelParallelism is true, motor programs can be prepared and executed in parallel so long as they don't overlap in the muscle groups used.

Compound commands

The motor buffer can also contain chunks derived from compound-motor-command. Compound motor commands allow you to execute primitive motor commands in a coordinated manner, even though they are not actual motor commands.

Preparation

Canonical ACT-R provides a separate chunk-type to specify a motor command to be prepared in advance and then executed later. The problem with this mechanism is that it locks you into a limited set of predefined movements (Specifically keyboard and mouse movements), preventing modelers from contributing their own movement types. jACT-R instead uses a meta-slot (:prepare-only) which can be added to any movement request. Using this, any movement command (past or future) can be prepared in advance, and then executed with the execute chunk-type request.