### 10.29 An Inverse of numbervars/3—`library(varnumbers)`

The built-in predicate `numbervars/3` makes a term ground by binding the variables in it to subterms of the form `'\$VAR'(`N`)` where N is an integer. Most of the calls to `numbervars/3` look like

```         numbervars(Term, 0, _)
```

which can be abbreviated to

```         numbervars(Term)
```

if you use this package.

`varnumbers/3` is a partial inverse to `numbervars/3`:

```         varnumbers(Term, N0, Copy)
```

unifies Copy with a copy of Term in which subterms of the form `'\$VAR'(`N`)` where N is an integer not less than N0 (that is, subterms which might have been introduced by `numbervars/3` with second argument N0) have been consistently replaced by new variables. Since 0 is the usual second argument of `numbervars/3`, there is also

```         varnumbers(Term, Copy)
```

This provides a facility whereby a Prolog-like data base can be kept as a term. For example, we might represent `append/3` thus:

```         Clauses = [
(append([], '\$VAR'(0), '\$VAR'(0)) :- true),
(append(['\$VAR'(0)|'\$VAR'(1), '\$VAR'(2), ['\$VAR'(0)|'\$VAR(3)]) :-
append('\$VAR'(1), '\$VAR'(2), '\$VAR'(3)))
]
```

and we might access clauses from it by doing

```         prove(Goal, Clauses) :-
member(Clause, Clauses),
varnumbers(Clause, (Goal:-Body)),
prove(Goal).
```

Exported predicates:

`numbervars(`+Term`)`
makes Term ground by binding variables to subterms `'\$VAR'(`N`)` with values of N ranging from 0 up.
`varnumbers(`+Term`, `-Copy`)`
xo succeeds when Term was a term producing by calling `numbervars(`Term`)` and Copy is a copy of Term with such subterms replaced by variables.
`varnumbers(`+Term`, `+N0`, `-Copy`)`
succeeds when Term was a term produced by calling `numbervars(`Term`, `N0`, `N`)` (so that all subterms `'\$VAR'(`X`)` have `integer(`X`)`, X` >= `N0) and Copy is a copy of Term with such subterms replaced by variables.

Send feedback on this subject.