Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!samsung!munnari.oz.au!goanna!ok From: ok@goanna.oz.au (Richard O'keefe) Newsgroups: comp.lang.prolog Subject: Re: loops in prolog Message-ID: <2934@goanna.oz.au> Date: 2 Mar 90 04:24:46 GMT References: <1032@fs1.ee.ubc.ca> <470003@hpbbi4.HP.COM> Organization: Comp Sci, RMIT, Melbourne, Australia Lines: 51 In article <470003@hpbbi4.HP.COM>, stefan@hpbbi4.HP.COM (#Stefan Bachert) writes: > I am not sure that you get me right with the idea of > once_true. So I repeat it here > once_true(X):-call(X),!. % predicate X is determinated > once_true(_). % and always true I am *sick* of seeing people reinvent once/1 and giving it new names. It is traditionally a library predicate in Edinburgh Prologs. I've even *more* sick of people thinking it is a good idea. If X is supposed to be determinate, then *WRITE* X so that it *IS* determinate, don't patch it up in the calls. When I see a program using once/1 I am willing to bet that it is badly written in other ways too. > loop:- > repeat, > once_true(action_1), > (not condition ; once_true(action_2),fail), !, > once_true(action_3). The actions should be written so that they are ALREADY determinate, if that is truly what is intended. The original author really did not make it clear. > Your proposal will still eat up the stack. Not so. Stack space is reclaimed on failure or on determinate exit, and tail calls don't take stack space in a modern Prolog. Recall that the recursive form of the loop was p :- action_1, p_loop. p_loop :- ( condition -> action_2, action_1, p_loop ; action_3 ). If action_1 and action_2 are determinate, then this loop does *NOT* "eat up the stack" in a decent Prolog system. (Note that in the 'repeat' form of the loop action_1 had better not fail, otherwise there's a nasty liitle infinite loop there. The recursive version has no such problem.) > PS: I don't like ->/2 because of its dubious definition. *WHAT* dubious definition? The if->then;else construct was defined quite clearly in the DEC-10 Prolog manual, as far back as 1979: ( P -> Q ; R ) is like call(( P, !, Q ; R )) except that it is transparent to cuts in Q and R ( P -> Q ) is like call(( P, !, Q )) except that it is transparent to cuts in Q How is this any more dubious than once/1?