Did you know ... Search Documentation:
Pack options -- prolog/options.pl
PublicShow source

This is a stoics.infrastructure pack for handling option arguments. The main concept is to treat options as naive Prolog lists which the programmer can manipulate and specialise if they need to, while providing a small number of predicates that manage basic common operations on options. Options are particularly important in the context of SWI packs, as making code publicly available to others often involves allowing for variations in the behaviour of the code.

The library provides simple extensions to the basic list manipulation predicates. In many cases it is just the error handling that is the main difference to standard predicates.

Technically the library is designed on the semantics of memberchk/2. Looking for an Option in a list of options, memberchk/2 will return the leftmost match. Library(options) sees options as a concatenation (append/3) of the user provided options (arguments for hereon) and the defaults provided by the predicate.

The default option values for a predicate are given by a predicate of the same name but postfixed by '_defaults'. The library also allows for reading user specific default options by reading profiles from a file located at $HOME/.pl/<pred_name>.pl, if that file exists. Each options file should have a number of option terms given as facts.

Some distinctive features of pack(options)

  • minimal "magic" behind the scenes
  • allows sloppy (un-listed) single option argument
  • defaults might depend on input
  • can-do cascading (options of distinct predicates should be disjoint)
  • processing debug(Dbg) terms which optionise calls to debug/1
  • uniform access to user specific file-based default options

For an example see program options_example_sort_defaults.pl in examples directory.

?- edit( pack(options/examples/ex_sort) ).

?- [pack(options/examples/ex_sort)].

?- ex_sort( [a,b,e,c,b], Ord, true ).
Ord = [a, b, c, e].
?- ex_sort( [a,b,e,c,b], Ord, debug(true) ).
% Input list length: 5
% Output list length: 4
Ord = [a, b, c, e].
?- ex_sort( [a,b,e,c,b], Ord, order(>) ).
Ord = [e, c, b, a].
?- ex_sort( [a,b,e,c,b], Ord, duplicates(true) ).
Ord = [a, b, b, c, e].

Create file $HOME/.pl/ex_sort.pl with content order(>).

?- ex_sort( [a,b,e,c,b], Ord, true ).
Ord = [e, c, b, a].

Default for user is now order(>) which can still be over-ridden at invocation

?- ex_sort( [a,b,e,c,b], Ord, order(<) ).
Ord = [a, b, c, e].

Pack info


Thanks to Jan Wielemaker for fixing an issue with expanding the $HOME variable and missing curly brackets in the errors DCG (2016/11/14).

- nicos angelopoulos
- 0.2.0 2015/7/5
- 0.4.0 2016/2/29
- 0.5.0 2017/3/10
- 1.0 2018/3/18
- 1.1 2018/4/8
- 1.2 2019/4/18
- 1.3 2020/9/18
- 1.4 2021/1/22
- 1.5 2022/12/29
See also
- http://www.stoics.org.uk/~nicos/sware/options
 options_version(-Version, -Date)
Current version and release date for the library.


?- options_version( Vers, Date ).
Date = date(2022,12,29),
Vers = 1:5:0.
 options(+Required, +Opts)
 options(+Required, +Opts, +OptionsOpts)
This should more naturally be option/2 but as this might cause confusion with Swi's own option library. Required can be a single or list of terms.

Opts can also be non list as it is passed through en_list/2.


when true it enlists the returning argument
should the selected option required to be ground, and what to do if not
dont do anything
throw error
only variable is allowed, if present the call always succeeds and TruthValue is bound to either true or false depending on underlying success of options/2 call
RemOpts is Opts after all functor/shape matching mentions of Required have been removed.

The predicate fails silently if the first Required option with equivalent "shape" in Opts fails to pattern match (unlike classic memberchk/2).

 ?- options( x(y), [x(x)] ).
 ?- options( x(y), [x(x),x(y)] ).

 ?- options( x(X), [a(b),c(d),x(y),x(x)] ).

 ?- options( [a(X),c(b)], [a(b),x(x),b(c)] ).
 ERROR: Required option: c(b), not present in options: [a(b),x(x)]
 % Execution Aborted
 ?- options( x(X), [a(b),c(d),x(y),x(x)], rem_opts(Rem) ).
 X = y,
 Rem = [a(b), c(d)].

 ?- options( x(X), [a(b),c(d),x(y),x(x)], en_list(true) ).
 X= [y].

 ?- options( a(A), [a(X),b(c)], ground(error) ).
 ERROR: pack(options): Option should be ground, but found: a(_G1470), in options: [a(_G1470),b(c)]
 ?- options( a(A), [a(X),b(c)], ground(true) ).
 ?- options( a(A), [a(X),b(c)] ).
 A = X.
 ?- options( a(A), [a(X),b(c)], ground(false) ).
 A = X.
 ?- options( a(b), [a(a),a(b),b(c)], true(T) ).
 T = fail.
 ?- options( a(A), [a(a),a(b),b(c)], true(T) ).
 A = a,
 T = true.
 ?- options( a(a), [a(a),a(b),b(c)], true(T) ).
 T = true.
- nicos angelopoulos
- 0.2 2015/01/16
- 0.3 2015/12/06 changed 3rd argument to Options of its own invocation

Undocumented predicates

The following predicates are exported, but not or incorrectly documented.

 options(Arg1, Arg2, Arg3)
 options_append(Arg1, Arg2, Arg3)
 options_append(Arg1, Arg2, Arg3, Arg4)
 options_call(Arg1, Arg2)
 options_call(Arg1, Arg2, Arg3)
 options_debug_topic(Arg1, Arg2, Arg3)
 options_debug(Arg1, Arg2, Arg3)
 options_propagate(Arg1, Arg2, Arg3, Arg4)
 options_restore(Arg1, Arg2)
 options_return(Arg1, Arg2)