A non-atomic term (NAT) is a way of specifying a term as a function of some other term(s). Every NAT is composed of a function and one or more arguments to that function.

Consider, for example, the function #$FruitFn, which takes as an argument a type of plant and denotes the collection of the fruits of that type of plant. This function can be used to build the following NATs:

(#$FruitFn #$AppleTree) (#$FruitFn #$PearTree) (#$FruitFn #$WatermelonPlant) . . . .

Note that there may or may not be a named CYC constant corresponding to the collection of apples (that is, a constant called #$Apple). The NAT (#$FruitFn #$AppleTree) provides a way of talking about this collection even if the corresponding constant does not exist.

NATs can be used anywhere a constant can be used. One could write, for example:

(#$implies (#$isa ?APPLE (#$FruitFn #$AppleTree)) (#$colorOfObject ?APPLE #$RedColor))

### 2.7.1. Functions

Since all NATs are built around functions, it’s important to understand more about them.

### 2.7.2. Function Arity

Like predicates, most functions have a fixed arity. A function is described as unary, binary, ternary, quaternary, or quintary, according to whether it takes 1, 2, 3, 4, or 5 arguments. Currently, there are only Skolem functions that take more than 5 arguments.

A few functions do not have a fixed arity, but can take a variable number of arguments. Mathematical functions like #$PlusFn are one example.

### 2.7.3. Function Argument Types and Result Types

Functions with fixed arity are similar to predicates in that the definition of the function must specify the type of each argument, using the predicates #$arg1Isa, #$arg2Isa, etc.

Functions with no fixed arity are defined using the predicate #$argsIsa, which specifies a single type of which every argument must be an instance.

Functions differ from predicates in that they return a CYC term as a result. Accordingly, function definitions must also describe the type of the result to be returned, using the predicate #$resultIsa. Consider, for example, the function #$GovernmentFn:

(#$arity #$GovernmentFn 1) (#$arg1Isa #$GovernmentFn #$GeopoliticalEntity) (#$resultIsa #$GovernmentFn #$RegionalGovernment)

The argument to #$GovernmentFn must always be an instance of #$GeopoliticalEntity, and a NAT created using #$GovernmentFn will always be an instance of #$RegionalGovernment. So, for instance,

(#$isa (#$GovernmentFn #$UnitedStatesOfAmerica) #$RegionalGovernment)

### 2.7.4. #$IndividualDenotingFunction vs. #$CollectionDenotingFunction

Most functions are instances of either #$IndividualDenotingFunction or #$CollectionDenotingFunction. #$GovernmentFn is an example of the former, since a NAT like (#$GovernmentFn #$UnitedStatesOfAmerica) denotes an individual government. On the other hand, #$FruitFn is an example of the latter, since a NAT like (#$FruitFn #$AppleTree) denotes the collection of all apples, not an individual apple.

The distinction between individuals and collections is an important one in CycL. For more on this topic, look at the constants #$Individual and #$Collection.

The definition of an instance of #$CollectionDenotingFunction should specify, not only its argument types and result type, but also the collection that the result will have as genls. This is done using the predicate #$resultGenl. For example, if the function #$LeftPairMemberFn is defined by:

(#$isa #$LeftPairMemberFn #$CollectionDenotingFunction) (#$arity #$LeftPairMemberFn 1) (#$arg1Isa #$LeftPairMemberFn #$SymmetricalPartType) (#$resultIsa #$LeftPairMemberFn #$ExistingObjectType) (#$resultGenl #$LeftPairMemberFn #$LeftObject)

then the following must be true concerning a NAT constructed from #$LeftPairMemberFn and #$Shoe:

(#$isa (#$LeftPairMemberFn #$Shoe) #$ExistingObjectType) (#$genls (#$LeftPairMemberFn #$Shoe) #$LeftObject)

In other words, the set of left shoes is an instance of #$ExistingObjectType and a subset of #$LeftObject.

### 2.7.5. Reifiable Functions vs. Unreifiable Functions

Many CycL functions are instances of #$ReifiableFunction. Each time an instance of #$ReifiableFunction is used with a new set of arguments to build a NAT, that NAT is reified. Reified NATs, also called NARTs, don’t have proper constant names, but can always be referred to by their NAT expression.

When a new NART is first created, CYC automatically sets up the correspondence

(#$termOfUnit NART NAUT)

where NART is the automatically created term and NAUT is the non-atomic unreified term that can be used to refer to it. In the CYC web interface, such an assertion might look like this:

(#$termOfUnit (#$GovernmentFn #$Canada) (#$GovernmentFn #$Canada))

It looks like the first and second arguments are the same, but that’s because NARTs are printed out using their EL formulas, i.e. their corresponding NAUT. If you look very carefully at any #$termOfUnit assertion in the web interface, you will see that the opening parenthesis of ARG1 is a followable link (depending on the web-browser you use, it may be underlined, or a different color), but the opening parenthesis of ARG2 is just opaque text. Clicking on the opening paren of a NAT will display the page for the NART the expression denotes.

Moreover, a NART can be explicitly equated with an existing constant using the predicate #$rewriteOf:

(#$rewriteOf #$TheYear1996 (#$YearFn 1996)) (#$rewriteOf #$Apple (#$FruitFn #$AppleTree))

When a NART is equated with a constant using #$rewriteOf, the two are asserted to be de dicto equivalent.

Skolem functions are reifiable.

Unreifiable functions include mathematical functions like #$PlusFn. Just because we use a NAT like (#$PlusFn 59 64) doesn’t mean we want to add to the KB a NART denoting the number 123. There are infinite ways to denote 123 by this method. If we want to talk about the number 123, we’ll just refer to it directly.

Also, #$UnitOfMeasure is not a subset of #$ReifiableFunction, so terms such as (#$Inch 37) and (#$Meter 500) are not reified when they are referred to.