OpenCogPrime:AbstractSchemaManipulation

From OpenCog
Jump to: navigation, search

Advanced Schema Manipulation

On this page we describe some special schema for manipulating schema, which seem to be very useful in certain contexts.

Listification

First, there are two ways to represent n-ary relations in OCP's Atom level knowledge representation language: using lists as in

f_list (x1, …, xn ) 

or using currying as in

f_curry x1, …, xn 

To make conversion between list and curried forms easier, we have chosen to introduce special schema (combinators) just for this purpose:

Listify f = f_list so that f_list (x1, …, xn ) = f x1 … xn 

Unlistify Listify f = f 

For instance

kick_curry Ben Ken

denotes

(kick_curry Ben) Ken

which means that kick is applied to the argument Ben to yield a predicate schema applied to Ken. This is the curried style. The list style is

kick_List (Ben, Ken)

where kick is viewed as taking as an argument the List (Ben, Ken). The conversion between the two is done by

listify kick_curry = kick_list

unlistify kick_list = kick_curry

As a more detailed example of unlistification, let us utilize a simple mathematical example, the function

(X- 1 )^2

As noted there, if we use the notations -, *, Square and Power to denote SchemaNodes embodying the corresponding operations, then then this formula may be written in variable-free node-and-link form as

ExOutLink
    pow
    ListLink
        ExOutLink
            -
            ListLink
                X
                1
        2

But to get rid of the nasty variable X, we need to first unlistify the functions pow and -, and then apply the C combinator a couple times to move the variable X to the front. This is accomplished as follows:

pow [ - [x,1], 2 ]
unlistify pow (-[x,1]) 2
C (unlistify pow) 2 (-[x,1])
C (unlistify pow) 2 ((unlistify -) x 1)
C (unlistify pow) 2 (C (unlistify -) 1 x)
B ( C (unlistify pow) 2) ( C (unlistify — ) 1) x

yielding the final schema

B ( C (unlistify pow) 2) ( C (unlistify — ) 1)

By the way, a variable-free representation of this schema in OCP would look like

ExOutLink
    B
    ExOutLink
        ExOutLink
            ExOutLink
                C
                ExOutLink
                    unlistify
                    pow
            2
            ExOutLink
                C
                ExOutLink
                    unlistify
                    -
        1

This representation may be difficult for the reader who lacks experience with functional programming. It involves the C combinator (discussed above), and the unlistify operator, defined so that e.g.

((unlistify f) x) (y) = f (x, y)

These concepts will be discussed in detail later, and used to do this example (and others) with more thorough explanation.

The main thing to be observed, however, is that the introduction of these extra schema lets us remove the variable X. The size of the schema is increased slightly in this case, but only slightly — an increase that is well-justified by the elimination of the many difficulties that explicit variables would bring to the system. Furthermore, there is a shorter rendition which looks like

ExOutLink
    B
    ExOutLink
        ExOutLink
            ExOutLink
                C
                pow_curried
            2
            ExOutLink
                C
                -_curried
        1

This rendition uses alternate variants of - and pow schema, labeled -_curried and pow_curried, which do not act on lists but are curried in the manner of combinatory logic and Haskell. It is 11 lines whereas the variable-bearing version is 8 lines, a trivial increase in length that brings a lot of operational simplification.

Finally, in case the indent notation is confusing, we give a similar example in a more standard predicate logic notation. We will translate the variable-laden predicate

likes(y,x) AND likes(x,y)

into the equivalent combinatory logic tree. Assume that the two inputs are going to be given to us as a list. Now, the combinatory logic representation of this is

S (B AND (B likes (listify C)) likes

using the standard convention of left-associativity for @.

We now show how this would be evaluated to produce the correct expression:

S (B AND (B likes (listify C)) likes (x,y)

S gets evaluated first, to produce

B AND (B likes (listify C)) (x,y) (likes (x,y))

now the first B

AND (B likes (listify C) (x,y)) (likes (x,y))

now the second one

AND (likes ((listify C) (x,y)) (likes (x,y)))

now the listified C

AND (likes (y,x)) (likes (x,y)) )

which is what we wanted.

Argument Permutation

In dealing with List relationships, there will sometimes be use for an argument-permutation operator

ListOfAtom PermuteArgumentList(Permutation p, ListOfAtom A)

The semantics are that

(P f) (v1,…, vn ) = f ( P (v1,…, vn ) )

where P is a permutation on n letters. This deals with the case where we want to say, for instance that

Equivalence parent(x,y) child(y,x)

Instead of positing variable names x and y that span the two relations parent(x,y) and child(y,x), what we can instead say in this example is

Equivalence parent ( PermuteArgumentList {2,1} child )

For the case of two-argument functions, argument permutation is basically doing on the list level what the C combinator does in the curried function domain. On the other hand, in the case of n-argument functions with n>2, argument permutation doesn't correspond to any of the standard combinators.