# EvaluationLink

The **EvaluationLink** provides a way for specifying the truth value of a predicate on a set of arguments. The general structure is

EvaluationLink <tv> PredicateNode some_p ListLink SomeAtom val_1 OtherAtom val_2

The above indicates that the predicate *some_p*, applied to arguments *val_1* and *val_2*, has the TruthValue tv = *some_p(val_1, val_2)*. So, for example:

EvaluationLink <true_tv> PredicateNode "LessThan" ListLink NumberNode 3 NumberNode 42

because 3<42 is true, and

EvaluationLink <false_tv> PredicateNode "LessThan" ListLink NumberNode 3 NumberNode 1

because 3<1 is false.

## Virtual Links

EvaluationLinks may exist as "real links", that is, links that can be found in the AtomSpace, or as virtual links, which cannot be found in the atomspace, and yet are still sometimes treated as if they really exist. The concept of a "LessThan" predicate is ideal for virtualization, as it is impossible to stuff the atomspace with real links holding all possible pairs of numbers.

Virtual links *always* use a GroundedPredicateNode, whereas real links always use an ordinary PredicateNode as the first atom in the link. See the article on virtual links for more information.

## Truth Values

The truth value semantics of EvaluationLinks is not one of conditional probability. Instead, it is given by the function or CombinatorTree that represents the corresponding Predicate. (?? unclear...)

**CAUTION**: in PLN, it is assumed that the truth value of EvaluationLink and MemberLink is a fuzzy-set-membership value, and NOT a probabilistic truth value. Neither the C++ code, nor the python or scheme wrappers distinguish these two types of truth values at this time. Combining these two different kinds of truth values can and will result in crazy results. *Caveat Emptor!*

## Bound and free variables

The variables that appear in an EvaluationLink are free variables; the implementation of the EvaluationLink in the C++ code uses the FreeLink to track the locations of variables in the EvaluationLink.

The truth value assignment given to an EvaluationLink by PLN is computed by implicitly assuming that it is wrapped by an AverageLink, and that all free variables within it are bound by the AverageLink. Thus, for example, the hypergraph

EvaluationLink <tv> PredicateNode "breathe" ListLink VariableNode "$X" ConceptNode "air"

is interpreted as being equivalent to

AverageLink <tv> VariableNode "$X" EvaluationLink PredicateNode "breathe" ListLink VariableNode "$X" ConceptNode "air"

that is, both of the above state that, on average, all things breath air with a truth value of <tv>.

## Equivalence to Concepts

One interesting way that a free variable in an EvaluationLink can be bound is with a SatisfyingSetLink. Thus, for example, in the hypergraph:

EvaluationLink PredicateNode "breathe" ListLink VariableNode "$X" ConceptNode "air"

the variable $X occurs as a free variable. It may be bound as follows:

SatisfyingSetLink <tv> VariableNode "$X" EvaluationLink PredicateNode "breathe" ListLink VariableNode "$X" ConceptNode "air"

The above is then equivalent to a ConceptNode, specifically:

ConceptNode "all-things-that-breathe-air" <tv>

Notice that the truth values <tv> are the same on each.

## Equivalence to subsets

In a similar manner to the above, one may expand:

EvaluationLink PredicateNode "breathe" ListLink ConceptNode "birds" ConceptNode "air"

It may be expanded as follows:

SubsetLink ConceptNode "birds" SatisfyingSetLink VariableNode "$X" EvaluationLink PredicateNode "breathe" ListLink VariableNode "$X" ConceptNode "air"

which could be read as: "birds form a subset of all things that breathe air".

## Beta reduction

The PLN rule MemberToEvaluationRule will take a MemberLink (i.e. a link that is a beta redex) and beta-reduce it to an EvaluationLink. The EvaluationToMemberRule performs the opposite conversion.

## Relation to ExecutionLink

There is an important conceptual relationship between EvaluationLinks and ExecutionLinks that is worth understanding.

From Model Theory, it is "well known" that functions and predicates (aka relations) are interchangable. So, for example, saying that "f(x,y)=z" is equivalent to saying that "it is true that p(x,y,z)" where p is a predicate (relation) that is true only when f(x,y)=z, and vice-versa. Thus, it is "well known" that any equational theory expressed in terms of functions can also be expressed in terms of relations, and vice-versa. This should be "obviously true", if you recall your grade-school/high-school teachers lecturing about algebraic varieties; it is sometimes said that model theory is algebraic geometry, but without the numbers.

The above may be expressed in OpenCog is as follows: "f(x,y) has the value z" is written as

ExecutionLink SchemaNode f ; name of the function ListLink ;; a list of the two input args Atom x Atom y Atom z ;; the output value of f.

Whereas "it is true that p(x,y,z)" is written as

EvaluationLink <true> PredicateNode p ; the name of the predicate ListLink ;; a list of the three args Atom x Atom y Atom z

The effective difference between these two is the indentation level for Atom z; in all other respects, they essentially convey the same idea ... with one important exception: when used with PLN, the truth value associated with the a fuzzy-set membership strength, and not a probabilistic truth value; what's more, Atom z is discarded entirely. In this case, we have that the correct interpretation of

EvaluationLink <strength> PredicateNode p ListLink Atom x Atom y

is that the pair (x,y) belong to the set p with a strength of 'strength'.

## Grounded and Defined predicates

EvaluationLinks that contain GroundedPredicateNodes and DefinedPredicateNodes can be evaluated at run-time to cause side-effects, and to obtain computed truth values. For example:

(cog-evaluate! (Evaluation (GroundedPredicate "py:foobar") (ListLink (Concept "baz") (Number 42))))

causes the python function *foobar* to be called, passing the atoms *(Concept "baz")* and *(Number 42)* as arguments.

DefinedPredicateNodes can be used in a similar manner. So, for example,

(cog-evaluate! (Evaluation (DefinedPredicate "Foobar Thing") (ListLink (Concept "baz") (Number 42))))

can be used with the following LambdaLink:

(DefineLink (DefinedPredicate "Foobar Thing") (LambdaLink (VariableList (Variable "$cc") (Variable "$nn")) (SequentialAnd ... (Variable "$cc") ... ... (Variable "$nn") ... )))

The defined predicate will be substituted, the variables will be beta-reduced, and the resulting expression will be evaluated, returning a truth value.

The PutLink also behaves a lot like an EvaluationLink, when it is used with DefinedPredicateNodes. In addition to the above, see PutLink for an example.

## As syntactic sugar

The current implementation of OpenCog has many custom link types created for special-purpose use. These link types are convenient, and handy, but are not really "fundamental" -- they should be understood as "syntactic sugar" for an EvaluationLink. Thus, for example, the NLP subsystem uses a PartOfSpeechLink to tag words with parts of speech:

PartOfSpeechLinkWordNode"automobile"DefinedLinguisticConceptNode"noun"

This should effectively be understood to be equivalent to

EvaluationLinkPredicateNode"PartOfSpeech"ListLinkWordNode"automobile"DefinedLinguisticConceptNode"noun"

Furthermore, both WordNode and DefinedLinguisticConceptNode are not "fundamental", but are in turn yet more syntactic sugar, which can be re-expressed using InheritanceLinks. So, at the fundamental level, one has:

EvaluationLinkPredicateNode"PartOfSpeech"ListLinkInheritanceLinkConceptNode"automobile"ConceptNode"Word"InheritanceLinkConceptNode"noun"ConceptNode"DefinedLinguisticConcept"

The difference between this last form, and the first, indicates why "syntactic sugar" is tasty.

## Proposed Variations

Some proposed variations of EvaluationLink are discussed on the IntensionalEvaluation page.