On this page:
10.1 %apply
10.2 %andmap

10 Higher-order Predicates

Logic variables which contain predicates may be used as the operator in predicate expressions:

> (%which ()
    (%let (p)
      (%and (%= p %knows)
            (p 'Odysseus 'TeX))))

'()

First the logic variable p is unified with the predicate %knows. In the expression

(p 'Odysseus 'TeX)

p is replaced by its value %knows to become

(%knows 'Odysseus 'TeX)

which succeeds.

This allows us to reason about predicates themselves. For example:

> (%which (p)
    (%member p (list %knows %parent))
    (p 'Odysseus 'Penelope))

'((p . #<procedure:relation>))

> (%more)

#f

Here we test which of the predicates %knows and %parent succeed when given the arguments 'Odysseus and 'Penelope.

The goal (%knows 'Odysseus 'Penelope) succeeds, but (%parent 'Odysseus 'Penelope) fails. Hence the only possible value for p is %knows.

However, logic variables used as a predicate must be instantiated. Since the set of defined predicates is not enumerable by Racklog, an unbound query will fail:

> (%which (p) (p 'Odysseus 'Penelope))

#f

We can define a higher-order predicate which tests for unary predicates that succeed with 'Odysseus as their argument:

(define (%odyssean p)
  (p 'Odysseus))

For example:

> (%which () (%odyssean %computer-literate))

'()

This succeeds because (%computer-literate 'Odysseus) succeeds.

> (%which () (%odyssean %compound))

#f

This fails because (%compound 'Odysseus) fails.

This also works if the predicate argument is a logic variable:

> (%which (p)
    (%member p (list %computer-literate %compound))
    (%odyssean p))

'((p . #<procedure:%computer-literate>))

Compare this with the example above.

Racklog also provides two predicates for defining relations involving arbitrary predicates.

10.1 %apply

The %apply predicate is analogous to convential Racket apply.

The goal

(%apply P L)

succeeds if L is a list with elements E, ..., and if P is a predicate that accepts as many arguments as there are Es, and if the goal (P E ...) succeeds. For example:

> (%which () (%apply %knows '(Odysseus TeX)))

'()

In this case, the goal

(%apply %knows '(Odysseus TeX))

is equivalent to

(%knows 'Odysseus 'TeX)

The list argument to %apply must be sufficiently instantiated to determine its length. The following goals succeed:

> (%which () (%apply %knows (list 'Odysseus 'TeX)))

'()

> (%which (X) (%apply %knows (list X 'TeX)))

'((X . Odysseus))

but it is not possible to use %apply with a list of unknown length:

> (%which (X Y) (%apply %knows (cons X Y)))

#f

10.2 %andmap

The %andmap predicate is analogous to convential Racket andmap.

The goal

(%andmap P L ...+)

succeeds if all the Ls are lists of equal length, and the goal (P E ...) succeeds for each set of elements E, ... of the Ls. For example:

> (%which () (%andmap %knows '(Odysseus Penelope) '(TeX Prolog)))

'()

In this case, the goal

(%andmap %knows '(Odysseus Penelope) '(TeX Prolog))

is equivalent to

(%and (%knows 'Odysseus 'TeX)
      (%knows 'Penelope 'Prolog))