(Redirected from Predicate)

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
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"
NumberNode 3
NumberNode 42
```

because 3<42 is true, and

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

because 3<1 is false.

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"
VariableNode "\$X"
ConceptNode "air"
```

is interpreted as being equivalent to

```AverageLink <tv>
VariableNode "\$X"
PredicateNode "breathe"
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"
VariableNode "\$X"
ConceptNode "air"
```

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

``` SatisfyingSetLink  <tv>
VariableNode "\$X"
PredicateNode "breathe"
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"
ConceptNode "birds"
ConceptNode "air"
```

It may be expanded as follows:

``` SubsetLink
ConceptNode "birds"
VariableNode "\$X"
PredicateNode "breathe"
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
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")
(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")
(Concept "baz")
(Number   42))))
```

can be used with the following LambdaLink:

```(DefineLink
(DefinedPredicate "Foobar Thing")
(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:

```PartOfSpeechLink
WordNode "automobile"
DefinedLinguisticConceptNode "noun"
```

This should effectively be understood to be equivalent to

```EvaluationLink
PredicateNode "PartOfSpeech"
WordNode "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:

```EvaluationLink
PredicateNode "PartOfSpeech"