## 4.14 Examining the program

current_atom(-Atom)
  Successively unifies Atom with all atoms known to the system. Note that current_atom/1 always succeeds if Atom is instantiated to an atom.
current_blob(?Blob, ?Type)
  Examine the type or enumerate blobs of the given Type. Typed blobs are supported through the foreign language interface for storing arbitrary BLOBS (Binary Large Object) or handles to external entities. See section 9.4.7 for details.
current_functor(?Name, ?Arity)
  Successively unifies Name with the name and Arity with the arity of functors known to the system.
current_flag(-FlagKey)
  Successively unifies FlagKey with all keys used for flags (see flag/3).
current_key(-Key)
  Successively unifies Key with all keys used for records (see recorda/3, etc.).
[ISO]current_predicate(:PredicateIndicator)
  True if PredicateIndicator is a currently defined predicate. A predicate is considered defined if it exists in the specified module, is imported into the module or is defined in one of the modules from which the predicate will be imported if it is called (see section 5.9). Note that current_predicate/1 does not succeed for predicates that can be autoloaded. See also current_predicate/2 and predicate_property/2.

  If PredicateIndicator is not fully specified, the predicate only generates values that are defined in or already imported into the target module. Generating all callable predicates therefore requires enumerating modules using current_module/1. Generating predicates callable in a given module requires enumerating the import modules using import_module/2 and the auto-loadable predicates using the predicate_property/2 `autoload`.

current_predicate(?Name, :Head)
  Classical pre-ISO implementation of current_predicate/1, where the predicate is represented by the head-term. The advantage is that this can be used for checking existence of a predicate before calling it without the need for functor/3:

      call_if_exists(G) :-
              current_predicate(_, G),
              call(G).

  Because of this intended usage, current_predicate/2 also succeeds if the predicate can be autoloaded. Unfortunately, checking the autoloader makes this predicate relatively slow; in particular because a failed lookup of the autoloader will cause the autoloader to verify that its index is up-to-date.

predicate_property(:Head, ?Property)
  True if Head refers to a predicate that has property Property. With sufficiently instantiated Head, predicate_property/2 tries to resolve the predicate the same way as calling it would do: if the predicate is not defined it scans the auto-import modules and finally tries the autoloader. Unlike calling, failure to find the target predicate causes predicate_property/2 to fail silently. If Head is not sufficiently bound, only currently locally defined and already imported predicates are enumerated. See current_predicate/1 for enumerating all predicates. A common issue concerns generating all built-in predicates. This can be achieved using the code below.

      generate_built_in(Name/Arity) :-
              predicate_property(system:Head, built_in),
              functor(Head, Name, Arity),
              \+ sub_atom(Name, 0, _, _, $).  % discard reserved names

  Property is one of:

  autoload(File)
    Is true if the predicate can be autoloaded from the file File. Like `undefined`, this property is not generated.
  built_in
    Is true if the predicate is locked as a built-in predicate. This implies it cannot be redefined in its definition module and it can normally not be seen in the tracer.
  dynamic
    Is true if assert/1 and retract/1 may be used to modify the predicate. This property is set using dynamic/1.
  exported
    Is true if the predicate is in the public list of the context module.
  imported_from(Module)
    Is true if the predicate is imported into the context module from module Module.
  file(FileName)
    Unify FileName with the name of the source file in which the predicate is defined. See also source_file/2 and the propery `line_count`. Note that this reports the file of the first clause of a predicate. A more robust interface can be achieved using nth_clause/3 and clause_property/2.
  foreign
    Is true if the predicate is defined in the C language.
  indexed(Head)
    Predicate is indexed (see index/1) according to Head. Head is a term whose name and arity are identical to the predicate. The arguments are unified with `1' for indexed arguments, `0' otherwise.
  interpreted
    Is true if the predicate is defined in Prolog. We return true on this because, although the code is actually compiled, it is completely transparent, just like interpreted code.
  iso
    Is true if the predicate is covered by the ISO standard (ISO/IEC 13211-1).
  line_count(LineNumber)
    Unify LineNumber with the line number of the first clause of the predicate. Fails if the predicate is not associated with a file. See also source_file/2. See also the `file` property above, notably the reference to clause_property/2.
  multifile
    Is true there may be multiple (or no) files providing clauses for the predicate. This property is set using multifile/1.
  meta_predicate(Head)
    If the predicate is declared as a meta-predicate using meta_predicate/1, Unify Head with the head-pattern. The head-pattern is a compound term with the same name and arity as the predicate where each argument of the term is a meta predicate specifier. See meta_predicate/1 for details.
  nodebug
    Details of the predicate are not shown by the debugger. This is the default for built-in predicates. User predicates can be compiled this way using the Prolog flag generate_debug_info.
  notrace
    Do not show ports of this predicate in the debugger.
  number_of_clauses(ClauseCount)
    Unify ClauseCount to the number of clauses associated with the predicate. Fails for foreign predicates.
  public
    Predicate is declared public using public/1. Note that without further definition, public predicates are considered undefined and this property is not reported.
  thread_local
    If true (only possible on the multi-threaded version) each thread has its own clauses for the predicate. This property is set using thread_local/1.
  transparent
    Is true if the predicate is declared transparent using the module_transparent/1 or meta_predicate/1 declaration. In the latter case the property `meta` is also provided. See chapter 5 for details.
  undefined
    Is true if a procedure definition block for the predicate exists, but there are no clauses for it and it is not declared dynamic or multifile. This is true if the predicate occurs in the body of a loaded predicate, an attempt to call it has been made via one of the meta-call predicates or the predicate had a definition in the past. See the library package `library(check)` for example usage.
  volatile
    If true, the clauses are not saved into a saved-state by qsave_program/[1,2]. This property is set using volatile/1.
dwim_predicate(+Term, -Dwim)
  `Do What I Mean' (`dwim') support predicate. Term is a term, which name and arity are used as a predicate specification. Dwim is instantiated with the most general term built from Name and the arity of a defined predicate that matches the predicate specified by Term in the `Do What I Mean' sense. See dwim_match/2 for `Do What I Mean' string matching. Internal system predicates are not generated, unless `style_check(+dollar)` is active. Backtracking provides all alternative matches.
[ISO]clause(:Head, ?Body)
  True if Head can be unified with a clause head and Body with the corresponding clause body. Gives alternative clauses on backtracking. For facts Body is unified with the atom true.
clause(:Head, ?Body, ?Reference)
  Equivalent to clause/2, but unifies Reference with a unique reference to the clause (see also assert/2, erase/1). If Reference is instantiated to a reference the clause's head and body will be unified with Head and Body.
nth_clause(?Pred, ?Index, ?Reference)
  Provides access to the clauses of a predicate using their index number. Counting starts at 1. If Reference is specified it unifies Pred with the most general term with the same name/arity as the predicate and Index with the index-number of the clause. Otherwise the name and arity of Pred are used to determine the predicate. If Index is provided Reference will be unified with the clause reference. If Index is unbound, backtracking will yield both the indices and the references of all clauses of the predicate. The following example finds the 2nd clause of member/2:

      ?- use_module(library(lists)).
      ...
      ?- nth_clause(append(_,_,_), 2, Ref), clause(Head, Body, Ref).
      Ref = <clause>(0x994290),
      Head = lists:append([_G23|_G24], _G21, [_G23|_G27]),
      Body = append(_G24, _G21, _G27).

clause_property(+ClauseRef, -Property)
  Queries properties of a clause. ClauseRef is a reference to a clause as produced by clause/3, nth_clause/3 or prolog_frame_attribute/3. Property is one of the following:
  file(FileName)
    Unify FileName with the name of the source file in which the clause is defined. Fails if the clause is not associated to a file.
  line_count(LineNumber)
    Unify LineNumber with the line number of the clause. Fails if the clause is not associated to a file.
  fact
    True if the clause has no body.
  erased
    True if the clause has been erased, but not yet reclaimed because it is referenced.