From the above, we conclude that we require reflective access to find
out whether an option is supported and valid for a particular predicate.
Possible option values must be described by types. Due to lack of a type
system, we use library(error)
to describe allowed option
values. Predicate options are declared using predicate_options/3:
- [det]predicate_options(:PI,
+Arg, +Options)
- Declare that the predicate PI processes options on Arg. Options
is a list of options processed. Each element is one of:
- Option(ModeAndType)
PI processes Option. The option-value must comply to
ModeAndType. Mode is one of + or - and Type is a type as accepted by must_be/2.
- pass_to(:PI,Arg) The option-list is passed to
the indicated predicate.
Below is an example that processes the option header(boolean)
and passes all options to open/4:
:- predicate_options(write_xml_file/3, 3,
[ header(boolean),
pass_to(open/4, 4)
]).
write_xml_file(File, XMLTerm, Options) :-
open(File, write, Out, Options),
( option(header(true), Options, true)
-> write_xml_header(Out)
; true
),
...
This predicate may only be used as a directive and is
processed by expand_term/2.
Option processing can be specified at runtime using assert_predicate_options/3,
which is intended to support program analysis.
- [semidet]assert_predicate_options(:PI,
+Arg, +Options, ?New)
- As predicate_options(:PI, +Arg, +Options). New
is a boolean indicating whether the declarations have changed. If New
is provided and
false
, the predicate becomes semidet and
fails without modifications if modifications are required.
The predicates below realise the support for compile and runtime
checking for supported options.
- [nondet]current_predicate_option(:PI,
?Arg, ?Option)
- True when Arg of PI processes Option.
For example, the following is true:
?- current_predicate_option(open/4, 4, type(text)).
true.
This predicate is intended to support conditional compilation using if/1
... endif/0. The
predicate
current_predicate_options/3
can be used to access the full capabilities of a predicate.
- [det]check_predicate_option(:PI,
+Arg, +Option)
- Verify predicate options at runtime. Similar to
current_predicate_option/3,
but intended to support runtime checking.
- Errors
- -
existence_error(option, OptionName)
if the option is not
supported by PI.
- type_error(Type, Value)
if the option is supported but
the value does not match the option type. See must_be/2.
The predicates below can be used in a development environment to
inform the user about supported options. PceEmacs uses this for
colouring option names and values.
- [nondet]current_option_arg(:PI,
?Arg)
- True when Arg of PI processes predicate options.
Which options are processed can be accessed using current_predicate_option/3.
- [nondet]current_predicate_options(:PI,
?Arg, ?Options)
- True when Options is the current active option declaration
for
PI on Arg. See predicate_options/3
for the argument descriptions. If PI is ground and refers to
an undefined predicate, the autoloader is used to obtain a definition of
the predicate.
The library can execute a complete check of your program using
check_predicate_options/0:
- [det]check_predicate_options
- Analyse loaded program for erroneous options. This predicate decompiles
the current program and searches for calls to predicates that process
options. For each option list, it validates whether the provided options
are supported and validates the argument type. This predicate performs
partial dataflow analysis to track option-lists inside a clause.
- See also
- derive_predicate_options/0
can be used to derive declarations for predicates that pass options.
This predicate should normally be called before
check_predicate_options/0.
The library offers predicates that may be used to create declarations
for your application. These predicates are designed to cooperate with
the module system.
- [det]derive_predicate_options
- Derive new predicate option declarations. This predicate analyses the
loaded program to find clauses that process options using one of the
predicates from
library(option)
or passes options to other
predicates that are known to process options. The process is repeated
until no new declarations are retrieved.
- See also
- autoload/0 may be used to complete the
loaded program.
- [det]retractall_predicate_options
- Remove all dynamically (derived) predicate options.
- [nondet]derived_predicate_options(:PI,
?Arg, ?Options)
- Derive option arguments using static analysis. True when Options
is the current derived active option declaration for PI
on
Arg.
- [det]derived_predicate_options(+Module)
- Derive predicate option declarations for a module. The derived options
are printed to the
current_output
stream.