A.15 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).