WELCOME TO SICStus Prolog Leading Prolog Technology |
|
SICStus Home > The Spider IDE > SPIDER Determinacy Analyzer | Download for Evaluation |
SPIDER Determinacy AnalyzerSPIDER automatically analyzes determinacy and nondeterminacy of predicates. The inferred information can be presented as problem or information markers and is shown in the info-pop documentation of predicates.The functionality is similar in spirit to, but not the same as, the one provided by the spdet tool and the Determinacy Checker library. The determinacy analyzer in SPIDER can help you spot unwanted nondeterminacy in your programs. SPIDER examines your program source code and points out places where nondeterminacy may arise. It is not in general possible to find exactly which parts of a program will be nondeterminate (or determinate) without actually running the program. However, SPIDER can find some, and perhaps most, unwanted nondeterminacy. Unintended nondeterminacy should be eradicated because:
Declaring NondeterminacySome predicates are intended to be nondeterminate. By declaring intended nondeterminacy, you avoid warnings about predicates you intend to be nondeterminate. Equally important, you also inform the determinacy analyzer about nondeterminate predicates. It uses this information to identify unwanted nondeterminacy. Nondeterminacy is declared by putting a declaration of the form:- name/arity is nondet. in your source file. This is similar to a dynamic or discontiguous declaration. Similarly, a predicate P/N may be classified as nondeterminate by the analyzer, whereas in reality, it is determinate. This may happen e.g. if P/N calls a dynamic predicate that in reality never has more than one (determinate) clause. To prevent false alarms arising from this, you can inform the analyzer about determinate predicates by declarations of the form: Using:- name/arity is semidet. is/2 as a directive in this way is supported natively
in SICStus Prolog 4.2.1. For older versions of SICStus, you can wrap
the directive in a conditional so that only SPIDER sees it, something
like:
A complete example would look like::- if current_prolog_flag(dialect, spider). :- name/arity is semidet. :- endif. % SPIDER An alternative, older, syntax is also available, see below.% parent.pl (this code requires SICStus Prolog 4.2.1) :- module(parent, [parent/2, is_parent/1]). :- parent/2 is nondet. parent(abe, rob). parent(abe, sam). parent(betty, rob). parent(betty, sam). :- is_parent/1 is nondet. is_parent(Parent) :- parent(Parent, _). What is DetectedIt is not, in general, possible to find exactly which places in a program will lead to nondeterminacy. The determinacy analyzer gives predicates the benefit of the doubt: when a predicate may be determinate, it will be assumed determinate. The analyzer will only report as nondeterminate places in your program that will be nondeterminate regardless of which arguments are bound.The determinacy analyzer looks for the following sources of nondeterminacy:
The above description is a simplification. In addition, the analyzer uses special knowledge about many builtins and library predicates and of the SICStus Prolog compiler to increase the accuracy of the inferred information. Analyzer ResultThe result of the analysis is used in two ways:
Integration with older versions of SICStus PrologNote: You can ignore this section if you use SICStus Prolog 4.2.1 or newer. SICStus Prolog 4.2.0 and older, and the accompanying determinacy checker tool, did not support the use ofis/2 as a directive. Instead
you would use a pseudo-directive det/1 and nondet/1
to declare a predicate as determinate and non-determinate,
respectively, as follows:
By default, SICStus Prolog does not recognize the% Older syntax, requires det/1 to be defined. :- det name/arity. % corresponds to: name/arity is semidet. :- nondet name/arity. % corresponds to: name/arity is nondet. nondet/1
and det/1 directives. Instead, they will be treated as calls
to undefined predicates and lead to errors during the loading of the
program and warnings in SPIDER.
One way to solve this is to define So, to make a long story short, to use the old syntax, do this after you have declared your module: and, when you want to declare the determinacy of some predicate you wrap that too in a conditional directive, so a complete example would look like::- if(current_prolog_flag(dialect, spider)). :- ensure_loaded(library(nondetdecl)). :- endif. By using conditional compilation only SPIDER sees the determinacy directives, thus ensuring that there are no costs when the code is compiled or loaded in SICStus Prolog.% parent.pl (this code works in any version of SICStus Prolog) :- module(parent, [parent/2, is_parent/1]). :- if(current_prolog_flag(dialect, spider)). :- use_module(library(nondetdecl)). :- endif. :- if(current_prolog_flag(dialect, spider)). :- nondet parent/2. :- nondet is_parent/1. :- endif. parent(abe, rob). parent(abe, sam). parent(betty, rob). parent(betty, sam). is_parent(Parent) :- parent(Parent, _).
Note: The documentation for |