How would you....

I must confess, the documentation for how all the pieces of this architecture go together is lacking. It is a continual process. However, most people once they find what they are looking for, are able to figure it out. The problem is often just getting that initial sense of what's going on, where and why.

In this series, I invite your questions. What would you like to do in jACT-R? Give me some time to think it through, and I'll give you a high-level explanation of how I would go about accomplishing this, with pointers to the relevant classes, coding conventions, and the like.

Ensure determinism

While our models are normally conceptualized as being stochastic, sometimes strict determinism is necessary. This is particularly true if you want to precisely replicate a run or for pedantic debugging. Strict determinism is actually quite difficult given the design decisions in jACT-R. The loose coupling of modules and asynchronous threading model make it possibly in only a very narrow sense. That having been said, the architecture has been designed to mitigate those problems as much as possible.

If you use the default modules, in a single model configuration, with programmatic perception, you can get deterministic runs. The moment another thread is introduced that manipulates the model at all, small non-determisms can arise. While jACT-R supports those manipulations in a thread-safe manner, it does so by queueing them up to be run on the model thread itself. This is a normal pattern for creating a model lock/semaphor when interfacing an experiment. In practice this manifests itself as a slight difference in the number of cycles executed between runs. Generally, 1 cycle over 6000, or 50ms over 5 minutes, simulated. In practice, this difference is usually insignificant.

If that is too much uncertainty, there are other solutions, both will kill your performance. You can either subsume the second thread within the model thread, or introduce specific synchronization points in model & experiment. In practice, only the second is feasible. The simplest mechanism is to synchronize the experiment with the stop of the model's cycle.  This forces the two threads into lock-step, removing the non-determism of the underlying thread timing.

jACT-R's default modules, when run in a single-threaded configuration, do run deterministically. The architecture tries to minimize non-determinisms introduced from other sources, but is ultimately designed to be performant under stochastic conditions. 

Inputs into modules...

An interesting question came up today at the ACT-R workshop. I was asked if I had a diagram of all the inputs and outputs of the various modules. It threw me off because the inputs and outputs of a module are going to be dictated by the design of that particular module*. For instance, the visual module only depends on a declarative module and its hook up to CommonReality via its visual memory. Then issues of neurological design came up, and where those communication pathways were represented within the module. I think this is where we started talking across each other. 

While the architecture (ACT-R, in general) is neurologically inspired, it is largely so post hoc. Canonical ACT-R's design existed before we started mapping modules to neurological regions, the same with jACT-R. Theoretically motivated design does not necessary require theorectically dictated implementation. For reasons of testability, extendability, and modification, we don't want to hinder our implementation with neurologic constraints - just the behavior

* but I should certainly provide such a diagram for the default modules. I'll consider that a question a valid bug report. Thanks, Ryan!