Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!linus!philabs!seismo!hao!hplabs!sri-unix!OKeefe.R.A.@EDXA From: OKeefe.R.A.@EDXA@sri-unix.UUCP Newsgroups: net.lang.prolog Subject: Some Thoughts On Assert & Retract Message-ID: <11970@sri-arpa.UUCP> Date: Fri, 30-Sep-83 02:57:34 EDT Article-I.D.: sri-arpa.11970 Posted: Fri Sep 30 02:57:34 1983 Date-Received: Wed, 28-Sep-83 02:49:13 EDT Lines: 49 From: Richard.HPS ( on ERCC DEC-10 ) ) You may already have seen my article in SigPlan where I say how horrible it is to use assert & retract and you really shouldn't do it. [ Unless the program is explicitly supposed to maintain a data base, in which case you have no real alternative. That's my excuse anyway, when people point the finger at records / recorded / erase in my code. ] I thought it might be generally interesting if I pointed out another pernicious effect of asserts and retracts on clauses. It is a general principal of language design that if you don't use a feature you shouldn't have to pay for it. Arithmetic expressions are like that; C Prolog version 1.2D.EDAI has 'succ' / 2, and if you want to use a predicate that has some pretence of reversibility, you can use succ / 2 instead of is / 2, and all you pay is the code space for the expression evaluator. So is the cut: the information that '!' needs to have kept for it to work has to be kept anyway, and if you haven't got any cuts you aren't paying anything for them. Assert and retract are not like that. There is a substantial overhead ( my guesstimate in C Prolog would be about 2-5% of the main loop costs ) in protecting the interpreter ( or the compiled code's state ) against the horrible things that assert and retract can do to predicates that happen to be running. 1. The local stack is reclaimed on determinate exit. If you have TRO, you can reclaim a little bit earlier than that. There is a lookahead technique which can spot determinacy much earlier: you label each clause with the principal functor of its first argument ( this might be an integer, or NIL for a variable ), and after you have found a clause that matches, you scan along the clause list for the next clause with the right first functor, and record that as the alternative instead of the next clause. This gives you the space saving benefits that clause indexing provides in the Dec-10 compiler, but not the time saving. However: if you are allowed to retract clauses in running predicates, you cannot use this technique. The clause you noted as the alternative might be retract before you get there! To get around this, whenever we retracted a clause we would have to scan the entire local stack seeing whether this clause was in there as an alternative, and doing something clever if it was. Asserting also does nasty things. The clause you assert might ***Sender closed connection*** === Network Mail from host su-score on Fri Sep 23 20:16:32 ===