🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.prolog
Article #4146

Re: incrementing values

#4146
From: Richard O'keefe
Date: Fri, 02 Feb 1990 05:46
70 lines
3293 bytes
In article <17467@megaron.cs.arizona.>, debray@cs.arizona.edu
 (Saumya K. Debray) writes:
[someone else wrote in another newsgroup that]
:> 	increment(Variable) :-
:> 		retract(value(Variable, OldValue)),
:> 		NewValue is OldValue + 1,
:> 		assert(value(Variable, NewValue)).
[is the way to implement x +:= 1 in Prolog and asked]
> Comments?

1.  There are three good ways of implementing X +:= 1 in Prolog,
    depending on what your Prolog has built in (there may be more):
	X1 is X0+1,		% portable
	plus(X0, 1, X1),	% C Prolog, NU Prolog, some others
	succ(X0, X1)		% C Prolog, insists that X0 >= 0.
    This is perfectly general:  any Pascal program using scalar variables
    can be transliterated to one where Prolog variables represent states
    of Pascal variables.  For example:
	function gcd(x, y: integer): integer;
	    begin
		assert((x > 0) and (y > 0));
		while x <> y do if x > y then x := x-y else y := y-x;
		gcd := x
	    end {gcd};
    transliterates to
	gcd(X, Y, Gcd) :-
		X > 0, Y > 0,
		gcd_loop(X, Y, Gcd).

	gcd_loop(X, Y, Gcd) :-
		( X =\= Y ->
		  ( X > Y -> X1 is X-Y, gcd_loop(X1, Y, Gcd)
		  ;          Y1 is Y-X, gcd_loop(X, Y1, Gcd)
		  )
		; Gcd is X
		).
    I'm not suggesting that this is the best way to write gcd/3 in
    Prolog, only that the transliteration is entirely mechanical and
    doesn't involve any asserts or retracts.

2.  It's often a good idea to use some other data structure to represent
    a number.  Instead of X1 is X0+1, a good choice may be X1 = [?|X0]
    (there is often something useful to put in the place of the ?).

3.  The code which the anonymous author provided has at least two flaws.
    (a) If a keyboard interrupt is received at the wrong time, and the
	program is then aborted, the counter may be destroyed.  Don't
	laugh, don't say it can't happen, I've known cases where it DID
	happen.  The more you hack variables in the data base instead of
	writing Prolog, the more likely it is.  In Quintus Prolog you
	can write
		clause(value(Var, N0), true, Ref),
		N1 is N0+1,
		begin_critical,
		erase(Ref),
		assert(value(Var, N1)),
		end_critical
	{note how the arithmetic was done _outside_ the critical region
	so that overflows and other errors don't leave the critical
	region unclosed.
    (b) retract/1 is NOT a determinate predicate.  In C Prolog, it can
	never be sure that it has reached the end of the predicate, so
	it has to leave a choice point.  In Quintus Prolog, retract/1
	uses first-argument indexing like everything else, but if
	first-argument indexing is not enough to spot the determinacy
	(e.g. if you try to hack an array this way by doing
		value(array(1,2,1020))				)
	then you're still going to get a choice point.   

There are other problems, but I'll leave them for other commentators.
Technical Details
Message-ID: <2834@goanna.oz.au>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!samsung!munnari.oz.au!bruce!goanna!ok
References: <17467@megaron.cs.arizona.edu>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!samsung!munnari.oz.au!bruce!goanna!ok
From: ok@goanna.oz.au (Richard O'keefe)
Newsgroups: comp.lang.prolog
Subject: Re: incrementing values
Summary: ask for comments and you'll get them...
Message-ID: <2834@goanna.oz.au>
Date: 2 Feb 90 05:46:01 GMT
References: <17467@megaron.cs.arizona.edu>
Organization: Comp Sci, RMIT, Melbourne, Australia
Lines: 70