Manual: Miscellaneous Packages


Quintus Prolog Manual


(PREV) (NEXT)

K-11: Miscellaneous Packages

K-11-1: ctr.pl

library(ctr) provides an array of 32 global integer variables. It was written some time ago for compatibility with another dialect of Prolog. The operations provided on these variables are

ctr_set(+Ctr, +N)
ctr[Ctr] := N
ctr_set(+Ctr, +N, ?Old)
Old is ctr[Ctr], ctr[Ctr] := N
ctr_inc(+Ctr)
ctr[Ctr] := ctr[Ctr] + 1
ctr_inc(+Ctr, +N)
ctr[Ctr] := ctr[Ctr] + N
ctr_inc(+Ctr, +N, ?Old)
Old is ctr[Ctr], ctr[Ctr] := ctr[Ctr] + N
ctr_dec(+Ctr)
ctr[Ctr] := ctr[Ctr] - 1
ctr_dec(+Ctr, +N)
ctr[Ctr] := ctr[Ctr] - N
ctr_dec(+Ctr, +N, ?Old)
Old is ctr[Ctr], ctr[Ctr] := ctr[Ctr] - N
ctr_is(+Ctr, ?Old)
Old is ctr[Ctr]

If you want to use these counters in a nestable construct, remember to reset them properly; for example,


count_solutions(Goal, Count) :-
        ctr_set(17, 0, Old),
        (call(Goal), ctr_inc(17), fail ; true),
        ctr_set(17, Old, X),
        Count = X.

 
This will work even if Goal contains a call to count_solutions/2, because the old counter value is saved on entry to the clause, and restored on exit. Contrast this with the following example:

count_solutions(Goal, Count) :-
        ctr_set(17, 0),
        (call(Goal), ctr_inc(17), fail ; true),
        ctr_set(17, X),
        Count = X.

 
In this example, if Goal contains a call to count_solutions/2, the inner call will clobber the counter of the outer call, and the predicate will not work.

This file is provided mainly to allow you to experience (by doing your own timing tests) that the foreign interface, not the data base, is the tool for hacking global variables in Prolog, provided that the global variables take only constants as values.

K-11-2: date.pl

library(date) is a time-stamp package.

The parameter ranges are

Year                                    year-1900                               (e.g. 1987 -> 87)
Month                                   0..11                                   (e.g. January -> 0, September -> 8)
Day                                     1..31                                   (e.g. 27 -> 27)
Hour                                    0..23                                   (e.g. midnight -> 0, noon -> 12)
Minute                                  0..59
Second                                  0..59
 
These parameter ranges are compatible with the UNIX library function localtime(3). Note that the range for months is not what you might expect.

The predicates provided are:

now(?When)
date(-DateNow)
date(+When, -DateThen)
time(-TimeNow)
time(+When, -TimeThen)
datime(-DatimeNow)
datime(+When, -DatimeThen)
datime(?Datime, ?Date, ?Time)
date_and_time(-DateNow, -TimeNow)
date_and_time(+When, -DateThen, -TimeThen)
portray_date(+TimeStamp)
time_stamp(+Format, -TimeStamp)
time_stamp(+When, +Format, -TimeStamp)

For example,


        | ?- date(X), portray_date(X).
        11-Jan-90
        X = date(90,0,11)

Note that if you want both the current date and time, you should call either datime/1 or date_and_time/2. It is an error to obtain the date and time in separate calls, because midnight could intervene and put you nearly 24 hours out.

Dates and datimes are also returned by directory_property/3 and file_property/3 (see library(directory)). All these records can be compared using term comparison.

The predicates time_stamp/[2,3] provide a way of creating a time-stamp atom using a special kind of format string. For example,


        | ?- time_stamp('%W, %d %M %y',Date).

        Date = 'Thursday, 11 January 1990'

 
The details of the format strings are explained in a comment in the sources. Please note that, in the interests of internationalization, time_stamp/[2,3] are likely to be superseded in a future release by something based on the ANSI C operation strftime(). The other predicates in this package will NOT change at that time.

K-11-3: Arbitrary Expressions -- library(activeread)

Languages such as Lisp allow you to read an expression and to evaluate it, returning a data structure. Prolog provides "evaluation" only for arithmetic expressions, and then only in certain argument positions. activeread.pl provides a new experimental facility for reading an arbitrary "expression" and "evaluating" it.


        | ?- active_read(InputTerm).

 
reads a term from the current input stream. If this term has the form

        X | Goal.

 
then Goal is called and InputTerm is unified with X. Otherwise, InputTerm is unified with the term which was read. Note that Goal may backtrack, in which case active_read/1 will also backtrack.

EXAMPLES:


        | ?- active_read(X).
        |: T | append([1,2],[3,4], T).
        X = [1,2,3,4]
        yes

        | ?- active_read(X).
        |: Front+Back | append(Front, Back, [1,2,3,4]).
        X = []+[1,2,3,4] ;
        X = [1]+[2,3,4] ;
        X = [1,2]+[3,4] ;
        X = [1,2,3]+[4] ;
        X = [1,2,3,4]+[] ;
        no

        | ?- active_read(X).
        |: abort.
        X = abort
        yes

NOTE: activeread.pl is not a module-file, but it is sufficiently small that there should be no problem with including a separate copy in each module where it is required.

K-11-4: addportray.pl

library(addportray) makes the use of portray/1 more convenient. In DEC-10 Prolog and C Prolog, a program could contain clauses like


        portray(X) :-
                should_be_handled_here(X),
                print_it_this_way

 
scattered through any number of files. In Quintus Prolog, this does not work, because each file will wipe out every other file's clauses for portray/1; in any case, a clause for portray/1 in a module will do nothing at all, because it is user:portray/1 which you must define. DEC-10 Prolog and C Prolog had a similar problem in that if you reconsulted a file containing such clauses, you lost all the other clauses for portray/1.

Now, in order to add a link to portray/1 clauses to your program, you can do the following:


        :- use_module(library(add_portray)).

        local_portray(X) :-
                should_be_handled_here(X),
                print_it_this_way(X).

        :- add_portray(local_portray).

 
To cancel such a link, you can call

        :- del_portray(local_portray).

Note that if you use this package, you should not define portray/1 in any other way; otherwise, these links will be lost.

You can link to other user-defined predicates (such as term_expansion/2) this way too. Suppose the other predicate to be linked to is user:Pred/Arity. Then


        :- add_linking_clause(Link, Pred, Arity).

 
ensures that there is a clause

        Pred(X1,...,XArity) :- Link(X1,...,XArity).

 
in module user:, where Link/Arity is called in the module from which add_linking_clause/3 is called, and

        :- del_linking_clause(Link, Pred, Arity).

 
ensures that there is no such clause. For example, you can add a case to term_expansion/2 by adding the following directive to a module:

        :- add_linking_clause(local_expander, term_expansion, 2).


Copyright (C) 1998 SICS
contact: product support sales information