AERA is implemented in in C++ and Replicode, the latter of which is also implemented in in C++. The Replicode programming language is based on principles of extensive pattern-matching and dynamic code production of short parallel programs and executable models. It is an interpreted language, designed specifically to meet the requirements of the AERA system, to enable fast generation and handling of the kind of compositional interrelated information required for dynamic planning and reasoning and cumulative learning.
Replicode is a functional language designed to implement the continuous forward chaining and backward chaining, i.e. deductions and abductions, that drives AERA learning. In other words, these two ways of exploiting knowledge are akin to, respectively, production and search.
Systems coded with Replicode are “distributed production systems,” where knowledge is stored in shared memory (which may be scattered across a cluster of computing nodes) and on which operations are event-driven (programs react automatically to the occurrence of knowledge), using pattern-matching to produce new knowledge. AERA, being in part implemented in Replicode, inherits based its fundamental principles to enable data-driven autonomous cumulative learning. An AERA agent’s knowledge may thus be composed of a possibly (very) large number of concurrent programs interacting in a global workspace.
This page gives a brief overview of Replicode. A longer introduction is given in this tech report, the material in the table below, and papers in the Publications section of this Website. The Replicode programming language, and the resulting AERA system (written in C and Replicode), are the work of a very small development team; hence, Replicode is neither a fully-implemented nor fully-explored approach, and it does not come with support, manuals, background theory, etc. or any guarantees expected from industrial-strenth programming languages. To those who wish to look into it we highly recommend delving into the AERA repository on GitHub.
|2013||Replicode: A Constructivist Programming Paradigm and Language|
|2013||Towards a Programming Paradigm for Control Systems With High Levels of Existential Autonomy|
Replicode relies on short parallel programs and executable models, enabling dynamic code production and extensive pattern-matching, whereby patterns target arbitrarily complex time series of objects. Patterns can be matched by any code in a given system, and at any depth in a knowledge objects’ structure. Knowledge is represented as Replicode objects – i.e. instances of Replicode classes - some of which are user-defined, others being part of the language’s built-in axioms. (Replicode does not use C++ object-oriented mechanisms for knowledge objects but instead defines its own mechanisms over C-like structures.)
Replicode language axioms
A full listing of Replicode’s axioms is too long to recount here; we let it suffice to mention a few of the unique ones: Entity - an element in the world or in the system; a symbol used to specify to whom some knowledge applies, be it an event, a prediction, a model, etc.; Marker - a Replicode object indicating a relation between two or more other Replicode objects; Notifications - objects that describe computational events that have occurred in the system. Fact - a predicate pointing to other objects and carries additional qualifications, in support of high-level first order logic programming; Prediction - a Replicode object indicating a fact that has not happened yet but may happen in the future. Composite State - a set of patterns specifying facts occurring at the same time. (Note: The C++ object-oriented mechanisms are not used for Replicode objects, but rather C-like program structures.)
Readability & dynamic compilation
As mentioned, Replicode is an interpreted language. It comes in a human-readable form that must be compiled into a machine-readable form – rCode - that is in turn interpreted at runtime; reciprocally, it can be decompiled from rCode back into human-readable form. An rCode interpreter, called rCore, is a tiny virtual machine capable of executing rCode programs. rCores are part of Replicode Executive - the other essential part is the memory, rMem. Replicode also defines a preprocessor (in C++ style) for managing code definitions, allowing developers to define custom object classes and macros.
Model-based & model-driven
Replicode supports the requirement of AERA of being fully event-driven. For this, Replicode allows actions (productions) to result from evaluating executable models (forward models to predict, inverse models to reach goals). Furthermore, the selection of models to be evaluated is not hard-coded, but is instead controlled by the execution of other models, which means that AERA is also model-driven.
Replicode is a programming language for specifying knowledge and algorithms that can reason about knowledge and algorithms. For this Replicode directly supports reflection, i.e. the evaluation of code produced by the system itself as part of its runtime operation. This meets the fundamental requirement for introspection that we hypothesize to be required in any architecture that needs to build models of itself. In this respect, the Replicode executive notifies programs - at runtime – of essential events that reflect the execution of code (for example, productions, invocation of commands issued to I/O devices, process spawning and termination, etc).
Replicode was designed to support the creation of cognitive architectures that rely on a constructivist paradigm, meaning systems that create their own knowledge based on their experience. As a result, Replicode has some very unusual properties, some of which are not found elsewhere. Needless to say, no other programming language offers the unified features of Replicode (if that were the case we would gladly have skipped the creation of Replicode.)
In Replicode, programs are produced autonomously and dynamically, and executed on the fly. All programs all run in parallel; sequentiality and synchronization are implicit, as they result from objects having been produced by some programs to become the inputs of some others. Replicode has no explicit loops: The execution is purely reactive (i.e. data-driven) and there is no way to loop around objects in the memory. There is no “and” operator: Conjunctions are achieved by assembling patterns and guards in sets, each of them bearing particular semantics (e.g. input section, timing constraints, etc.). Neither is there an “or” operator: Disjunctions are achieved by running different programs and/or models targeting the different cases that would have constituted the operands of the desired disjunction. Replicode represents knowledge as non-axiomatic logic expressions: “Truth” is always subject to interpretation by programs and models. In other words, knowledge can be incomplete, context-dependent, and does not reflect any absolute truth but reflects instead what the system has learned so far from its experience.
The key source for these features - and other peculiarities of Replicode - has to do with requirements on the self-bootstrapping of self-supervised learning agents: If a learning agent experiences something very new (that its programmers did not foresee) it must be able to autonomously construct knowledge about that experience that enables it to better achieve goals with respect to that experience (whether it is about a life-or-death situation or something more mundane). To do so it must be able to understand programs and programming, and for that to be possible the semantics of the programming paradigm it uses must not be so complex as to require the agent to be smarter than it already it. In other words, a self-programming paradigm must place the bar low enough for bootstrapping but flexible enough for continued knowledge growth and cognitive development. This is a fundamental impetus for Replicode.