From OpenCog
Jump to: navigation, search

In OpenCog, an Atom captures the notion of an atomic formula (or atom) in mathematical logic. The primary differences between the concept of atoms in logic, and the concept of Atoms in OpenCog is that OpenCog Atoms have TruthValues that are more general than 'true' or 'false'. Another important difference is that AndLink and OrLink are Atoms themselves, and can be used to combine other Atoms, and so OpenCog does not draw a clear distinction between atomic formulas and atomic sentences: both are given equal footing. Likewise, the ForAllLink and ExistsLink are Atoms that are analogs for the logic expressions x and y, while LambdaLink corresponds to the lambda-calculus notion of λx. Patterns with variables to be grounded are specified using the BindLink.

Atoms as types

Because all Atoms in OpenCog carry an immutable type, they can be understood as terms, in the sense of logic or type theory. Atoms are just type instances.

Atoms as symbols

Atoms are normally stored in an atomspace, and, when they are placed in the atomspace, they become unique. Thus, in comparison to other programming languages, atoms can be understood to be the same thing as symbols, and the atomspace is essentially the same thing as a symbol table. A symbol table commonly has the property that all symbols in it are unique.

Once an atom is placed in the atomspace, it gets a single, unique ID. This unique ID is the string name of a Node, and it is the outgoing set of a Link.

In the Ruby programming language, symbols are called atoms. This is not an accident! Likewise, symbols are called atoms in Prolog. However, Prolog distinguishes atoms, variables and (compound) terms; OpenCog does not. Thus, the VariableNode plays the role of a Prolog variable, and a Link is the OpenCog analog of a compound term.

Both LISP and Guile allow parameters to be attached to symbols. These are analogous to the values that can be attached to atoms, described below.


A TruthValue gives each Atom a valuation or an interpretation; thus all Atoms in a given, fixed AtomSpace always carry a default valuation/interpretation along with them. Additional interpretations can be created by using contexts and the ContextLink. When contexts are used, truth values resemble conditional probabilities; that is, the truth value of an atom A in context C can be roughly understood to behave as a probability P(A|C).

The more complex and more general notion of an interpretation or structure in model theory is handled by means of the EquivalenceLink and the SatisfyingSetLink. Atoms can be placed into multiple atom spaces for various convenience calculations.

The EvaluationLink allows a relational model to be specified (again, in the sense of model theory), and thus, the collection of Atoms in an AtomSpace can be thought of as being a generalization of a relational database. In a certain sense, the EvaluationLink is the most central and important atom type in OpenCog, as it is how OpenCog implements knowledge representation.

The atom types page provides a general overview of the various different atom types; see the Category:Atom Types for an index of the atom types currently in use.

Atom Types

Main article: Atom types

All Atoms in the AtomSpace have a type. The two most basic types of Atoms are the Node and the Link. The types form a type hierarchy: all atoms inherit from the type "Atom", and the type Atom itself inherits from ProtoAtom. The ProtoAtom is itself the base type for values (such as truth values) as well as atoms.

The list of supported atom types can be found in Category:Atom Types.

There is an infrastructure for working with atom types: these are the type constructors, of which the TypeNode, the SignatureLink, the ArrowLink and the TypeSetLink are all examples. Polymorphic types can be specified using the TypeChoice link. The type, and more generally, the signature, can be checked with the type checker.


Atoms are implemented as C++ classes (with bindings for scheme, python and haskell.) Many atom types (in fact, most atom types) provide some specialized operation, such as searching for patterns, adding two numbers, beta-reducing an expression or distinguishing between free and bound variables. The code to perform these specialized operations is implemented in C++. Thus, many/most atoms are executable: they have a C++ method on them to "run" the operation that they implement. For the users of Atomese, these programming API's are irrelevant, and thus are not documented here. The API's are for the system programmers only; for everyone else, it is sufficient to create Atoms and place them into the atomspace, and then trigger execution.

Note: at this time, all specialized Atom code is written in C++. In principle, other languages could be ("easily") supported; in practice this has not been done. In practice, most users find that the GroundedSchemaNode and the GroundedPredicateNode are sufficient for practical applications.

The practical, day-to-day API that all users should use for ordinary applications is best explained through the examples.