Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!think.com!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!ucbvax!vax.oxford.ac.uk!POPX From: POPX@vax.oxford.ac.uk (Jocelyn Paine) Newsgroups: comp.lang.prolog Subject: Trapping interrupts cleanly Message-ID: <9105310922.AA22183@ucbvax.Berkeley.EDU> Date: 31 May 91 09:22:00 GMT Sender: daemon@ucbvax.BERKELEY.EDU Lines: 67 Newsgroups: comp.lang.prolog Subject: Trapping interrupts cleanly Summary: Expires: Sender: Reply-To: popx@vax.ox.ac.uk (Jocelyn Paine) Followup-To: Distribution: comp.lang.prolog Organization: Experimental Psychology, Oxford University, UK. Keywords: I'd be interested to know whether there are any Prologs that handle interrupts in a way that doesn't destroy functional purity. Let me explain. I have a command-interpreter written in Prolog whose main loop is of the form mainloop :- read_command( C ), obey( C ), mainloop. The interpreter has to maintain some internal state (if it didn't, it would be about as interesting as those Prolog systems that reply "no" regardless of what you ask them). This state is interrogated by some commands, and can be changed by others. How to represent this? The dirty way would be as clauses. To change state, obey would retract and reassert one or more of these clauses. The clean way is by holding the state as an argument mainloop( State ) :- read_command( C ), obey( C, State, NewState ), mainloop( NewState ). where NewState is the effect of command C acting on State. I suppose all Prolog implementations _are_ now capable of tail-recursion-optimising this kind of loop and of garbage collecting the inacessible components of State? But the need to trap interrupts seems to destroy this purity. Some of the commands are listing commands: they may generate several screenfuls of output. I want users to be able to interrupt them with a CONTROL-C (I'm using a VAX), and then to have my interpreter call mainloop with whatever State was in force when the interrupt occurred. Now, I'm using Poplog Prolog. In this, you can nominate a predicate to be obeyed whenever CONTROL-C is typed. (For those who know Pop-11, you do so by assigning to the system procedure "interrupt"). But the only way to pass the State to the interrupt predicate is by doing something like mainloop( State ) :- read_command( C ), retractall( interrupt_goal(_) ), assert( interrupt_goal( mainloop(State) ), obey( C, State, NewState ), mainloop( NewState ). and arranging for the interrupt predicate to do interrupt_goal( G ), call( G ). This enforces an assert/retract pair on each cycle. If I have to do that, I might as well go back to representing the whole state as database assertions! The only other Prolog I've used extensively is ESL Prolog-2, and it doesn't provide any cleaner solution to this problem. Are there any Prologs that do? What is considered good style on those that don't? Jocelyn Paine