Prev Next Up Home Keys Figs Search New

Argument Passing via Assert

Appeared in Volume 9/2, May 1996

Keywords: assert.


st14@ukc.ac.uk
S.Tobies
15th February 1996

I have to write a predicate which, in exceptional cases, needs some additional arguments which tend to be quite large ground terms. Would it make sense to pass these arguments using assert/retract, or is that bad style?

pred(normal_case, Arguments) :- 
    some_recursive_processing(Arguments).
pred(exceptional_case, Arguments) :-
    pred_additional_arguments(AddArgs),
    some_processing(Arguments, AddArgs).

calling_predicate(Args, AddArgs) :-
    assert(pred_additional_arguments(AddArgs)),
    pred(Args),
    retract(pred_additional_arguments(AddArgs)). 


dominic@.aethos.demon.co.uk
Dominic Binks
15th February 1996

It's not just bad style, it's also likely to be fairly inefficient because most Prolog's are not good at asserting large terms.

It would be better to explicitly pass all the arguments, and ignore the extra arguments when you don't need them. A less clear, but acceptable solution, would be to abuse Prolog's lack of typing and pass them as a list of extra arguments, passing [] when no arguments are needed. You might use the latter technique if you need a variable number of arguments.


ok@goanna.cs.rmit.edu.au
Richard A. O'Keefe
20th February 1996

In response to S.Tobies:

No, it would not make sense. Asserting and retracting are S... L... O...W!

By the way, if you were going to do that, it would be better to:

assert(pred_additional_arguments(AddArgs), Data_Base_Ref),
( pred(Args) -> Flag = true ; Flag = false ),
erase(Data_Base_Ref),
Flag == true.

You've already wrapped the stuff up as one data structure, so argument passing will be cheap. The only problem is that it adds bulk to your source code. So, use the term_expansion/2 hook. All you have to do is say:

a clause of the form H <<- B
translates to H' :- B'

where H' and B' are obtained by adding an extra last argument X to all visible goals.

Then you would write:

pred(normal_case, Usual_Args) <<-
    ....
pred(exceptional_case, Usual_Args) <<-
    unusual_info(foo(X)),
    ...

where something like:
unusual_info(foo(Foo), pred_additional_arguments(_,_,_,Foo,_,_,_)).

The "The Craft of Prolog" tells you what you need to know. (Plug plug :-)


luutran@cs.sci.csupomona.edu
Luu Tran
20th February 1996

I realize this is dependent on the implementation, but in general, how do assert/retract compare to record/recorded in term of efficiency?


bimbart@cs.kuleuven.ac.be
Bart Demoen
21st February 1996

No general rule here: in some Prologs, record is just a form of assert and similar in slowness. In others (e.g. ProLog by BIM) you get better indexing for record/recorded and better use-once performance. But record/recorded is not in ISO Prolog.

There was a paper several years ago in Information Processing Letters (I think) by some people from Finland, who discussed the performance tradeoff between using predicate arguments or assert/retract for passing information: the conclusion was more than just "assert/retract is slow". But it is almost always true.

O'Keefe wrote:
By the way, if you were going to do that, it would be better to...

Not very good advice given the current standard for Prolog :-)


ok@goanna.cs.rmit.edu.au
Richard A. O'Keefe
22nd Feb 1996

Luu Tran writes:
how do assert/retract compare to record/recorded

They have to do essentially the same thing. In DEC-10 Prolog, C Prolog, and the versions of Quintus Prolog whose insides I knew anything about, the major differences were:

For bodiless clauses, I would be surprised if there was much difference; depending on your particular system and problem, perhaps a factor of 2. Whatever the ratio, it is still spectacularly slow compared with argument passing.

Also, bear in mind that "pure" code is significantly easier to debug. You can use declarative debugging techniques, and even in their absence it is still possible to "roll back".

Prev Next Up Home Keys Figs Search New