▼ |  | Racklog: Prolog-Style Logic Programming

1 | Simple Goals and Queries
2 | Predicates
3 | Using Conventional Racket Expressions in Racklog
4 | Backtracking
5 | Unification
6 | Conjunctions and Disjunctions
7 | Manipulating Racklog Variables
8 | The Cut (!)
9 | Set Predicates
10 | Higher-order Predicates
11 | Racklog Module Language
12 | Glossary of Racklog Primitives
| Bibliography

► | 10 | Higher-order Predicates

10.1 | %apply
10.2 | %andmap

On this page:

10.1`` %apply
10.2`` %andmap

top ← prev up next →

### 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))

top ← prev up next →