- Documentation
- Reference manual
- The SWI-Prolog library
- library(aggregate): Aggregation operators on backtrackable predicates
- library(ansi_term): Print decorated text to ANSI consoles
- library(apply): Apply predicates on a list
- library(assoc): Association lists
- library(broadcast): Broadcast and receive event notifications
- library(charsio): I/O on Lists of Character Codes
- library(check): Consistency checking
- library(clpb): CLP(B): Constraint Logic Programming over Boolean Variables
- library(clpfd): CLP(FD): Constraint Logic Programming over Finite Domains
- library(clpqr): Constraint Logic Programming over Rationals and Reals
- library(csv): Process CSV (Comma-Separated Values) data
- library(dcg/basics): Various general DCG utilities
- library(dcg/high_order): High order grammar operations
- library(debug): Print debug messages and test assertions
- library(dicts): Dict utilities
- library(error): Error generating support
- library(gensym): Generate unique identifiers
- library(intercept): Intercept and signal interface
- library(iostream): Utilities to deal with streams
- library(lists): List Manipulation
- library(main): Provide entry point for scripts
- library(nb_set): Non-backtrackable set
- library(www_browser): Activating your Web-browser
- library(occurs): Finding and counting sub-terms
- library(option): Option list processing
- library(optparse): command line parsing
- library(ordsets): Ordered set manipulation
- library(pairs): Operations on key-value lists
- library(persistency): Provide persistent dynamic predicates
- library(pio): Pure I/O
- library(predicate_options): Declare option-processing of predicates
- library(prolog_pack): A package manager for Prolog
- library(prolog_xref): Prolog cross-referencer data collection
- library(quasi_quotations): Define Quasi Quotation syntax
- library(random): Random numbers
- library(readutil): Read utilities
- library(record): Access named fields in a term
- library(registry): Manipulating the Windows registry
- library(settings): Setting management
- library(simplex): Solve linear programming problems
- library(solution_sequences): Modify solution sequences
- library(thread_pool): Resource bounded thread management
- library(ugraphs): Unweighted Graphs
- library(url): Analysing and constructing URL
- library(varnumbers): Utilities for numbered terms
- library(yall): Lambda expressions

- The SWI-Prolog library
- Packages

- Reference manual

## A.22 library(nb_set): Non-backtrackable set

The library `library(nb_set)`

defines *non-backtrackable
sets*, implemented as binary trees. The sets are represented as
compound terms and manipulated using nb_setarg/3.
Non-backtrackable manipulation of datastructures is not supported by a
large number of Prolog implementations, but it has several advantages
over using the database. It produces less garbage, is thread-safe,
reentrant and deals with exceptions without leaking data.

Similar to the `library(assoc)`

library, keys can be any
Prolog term, but it is not allowed to instantiate or modify a term.

One of the ways to use this library is to generate unique values on
backtracking *without* generating *all* solutions first,
for example to act as a filter between a generator producing many
duplicates and an expensive test routine, as outlined below:

generate_and_test(Solution) :- empty_nb_set(Set), generate(Solution), add_nb_set(Solution, Set, true), test(Solution).

**empty_nb_set**(`?Set`)- True if
`Set`is a non-backtrackable empty set. **add_nb_set**(`+Key, !Set`)- Add
`Key`to`Set`. If`Key`is already a member of`Set`, add_nb_set/3 succeeds without modifying`Set`. **add_nb_set**(`+Key, !Set, ?New`)- If
`Key`is not in`Set`and`New`is unified to`true`

,`Key`is added to`Set`. If`Key`is in`Set`,`New`is unified to`false`

. It can be used for many purposes:`add_nb_set(+, +, false)`

Test membership `add_nb_set(+, +, true)`

Succeed only if new member `add_nb_set(+, +, Var)`

Succeed, binding `Var` **gen_nb_set**(`+Set, -Key`)- Generate all members of
`Set`on backtracking in the standard order of terms. To test membership, use add_nb_set/3. **size_nb_set**(`+Set, -Size`)- Unify
`Size`with the number of elements in`Set`. **nb_set_to_list**(`+Set, -List`)- Unify
`List`with a list of all elements in`Set`in the standard order of terms (i.e., an*ordered list*).