🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.prolog
Article #1125

Re: Prolog PROG TECH. II

#1125
From: jgarland
Date: Sun, 19 Aug 1990 18:53
93 lines
4840 bytes
In article <3581@goanna.cs.rmit.oz.au>, ok@goanna.cs.rmit.oz.au 
(Richard A. O'Keefe) proposes the following structure to help Tim 
G. with some confused code and expresses doubts as to whether Mr. G's 
PDC Prolog can handle it.
 
> 	run(done) :- !.
> 	run(Event) :- /* Event ~= done */
> 	    exec_event(Event, NextEvent),
> 	    run(NextEvent).
> 		
> If exec_event/2 is determinate, this is determinate.
> If exec_event/2 is not determinate, this is not determinate.
> 
I say again, that I agree PDC (Turbo) Prolog cannot directly do some of the 
interesting things other Prologs do.  However, Tim's question revolved around 
memory conservation, not metaprogramming.  Nothing he has proposed in any of
his inquiries remotely requires that level of sophistication.  His code is 
awful [sorry Tim]--but then mine, at least, was too...once.

 I wasn't going to reply to your question as I am clueless wrt your published 
 code.  However, I do want to mention some TP memory management points.

 I have taken the liberty of reworking the O'Keefe code in PDC Prolog.  
 I implied in an earlier post to you that non-determinism is important for
 saving stack space on recursive calls. It is, but the crucial point is whether 
 backtracking points are generated.  Note that exec_event/2 below is non-deter-
 ministic--i.e. *capable* of generating backtracking points.  With the proper
 ordering of exec_event/2 clauses, however, backtracking points can be elimi-
 nated by tail recursion optimization.  Or, more brutally, you can simply 
 place a cut after the non-deterministic clause and before the recursive call.

 BTW, it is important to differentiate between heap and stack usage as this
 gives you important information about errors.  Running out of heap (also 
 *global* stack) space comes from declaring super-long lists (e.g. 40,000 
 integers on my machine) having just plain too many database facts, windows,
 etc., or clumsy usage of the database predicates chain_terms/5 or ref_term/4.
 It's rarely a problem except with runaway loops.  *Stack* space is consumed
 by recursive calls which cannot be eliminated through tail recursion, by
 parameter passing, by temporary storage of subgoals, etc.  It is often a 
 problem under any situation which generates large numbers of backtracking
 points (recursion being an easy way to do this).

 So, if the O'Keefe structure is of use to you, have no fear of using it.  If 
 it isn't, remember that backtracking points are the thing to focus on...there
 mustn't be any before the recursive call if you want to keep them from being 
 multiplied. */
****************************Listing***********************************
shorttrace

predicates

  run(symbol)
  exec_event(symbol,symbol)

clauses

  run(done) :- write("EVENT HAPPENED"),nl,!.
  run(Event) :- /* Event ~= done */
    storage,
    exec_event(Event, Nextevent),
%   !,                        % putting a cut here would eliminate any 
                              % problems with leftover backtracking points
                              % below, but by ordering in the suggested way,
                              % you eliminate the need for a cut here.
    run(NextEvent).	

  exec_event(_,NextEvent) :-  % This clause should fail on all calls
                              % but the last.
        
     random(100,Done_or_not), % loop for a random while and see if we generate
                              % any backtracking points (or consume memory).
                              
     Done_or_not < 10,        % Succeed randomly 1/10th of the time.
     Nextevent = done.
     
  exec_event(_,not_done).     % This clause should succeed leaving no untried
                              % alternatives on every iteration but the last.  
goal

   run(xxx).  % anything other than an underscore, a variable, or 'done'
****************end of listing**********************************************   
   
    A last note: 
    Prolog in general, including PDC Prolog, is generally very elegant--if your
    programme looks inelegant, that is usually a clue you haven't quite
    got the algorithm--and your thinking--down quite right yet.  [This is not
    personal, it's part my own evaluation process for my own code.]

 
 John Garland
 
 jgarland@mun                Bitnet
 jgarland@kean.ucs.mun.ca    Internet
Technical Details
Message-ID: <126688@kean.ucs.mun.ca>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!stretch.cs.mun.ca!leif!jgarland
References: <ganNChe00WB2QF5VM0@andrew.cmu.edu> <3581@goanna.cs.rmit.oz.au>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!stretch.cs.mun.ca!leif!jgarland
From: jgarland@kean.ucs.mun.ca
Newsgroups: comp.lang.prolog
Subject: Re: Prolog PROG TECH. II
Message-ID: <126688@kean.ucs.mun.ca>
Date: 19 Aug 90 18:53:20 GMT
References: <ganNChe00WB2QF5VM0@andrew.cmu.edu> <3581@goanna.cs.rmit.oz.au>
Organization: Memorial University. St.John's Nfld, Canada
Lines: 93