9 Set Predicates
The goal
(%bag-of X G Bag)
unifies with Bag the list of all instantiations of X for which G succeeds. Thus, the following query asks for all the things known – ie, the collection of things such that someone knows them:
| ||||
'((things-known TeX Racket Prolog Penelope TeX Prolog Odysseus TeX calculus archery)) |
This is the only solution for this goal:
> (%more) |
#f |
Note that some things – eg, TeX – are enumerated more than once. This is because more than one person knows TeX. To remove duplicates, use the predicate %set-of instead of %bag-of:
| ||||
'((things-known TeX Racket Prolog Penelope Odysseus calculus archery)) |
In the above, the free variable someone in the %knows-goal is used as if it were existentially quantified. In contrast, Prolog’s versions of %bag-of and %set-of fix it for each solution of the set-predicate goal. We can do it too with some additional syntax that identifies the free variable. Eg,
| ||||||
'((someone . Odysseus) (things-known TeX Racket Prolog Penelope)) |
The bag of things known by one someone is returned. That someone is Odysseus. The query can be retried for more solutions, each listing the things known by a different someone:
> (%more) |
'((someone . Penelope) (things-known TeX Prolog Odysseus)) |
> (%more) |
'((someone . Telemachus) (things-known TeX calculus)) |
> (%more) |
'((someone . Odysseus) (things-known archery)) |
> (%more) |
#f |
Racklog also provides two variants of these set predicates, viz., %bag-of-1 and %set-of-1. These act like %bag-of and %set-of but fail if the resulting bag or set is empty.