# OpenCogPrime:AbstractSchemaManipulation

## Contents

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
-
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
C
unlistify
pow
2
C
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
C
pow_curried
2
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.