Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!linus!philabs!seismo!hao!hplabs!sri-unix!SHardy@SRI-KL From: SHardy%SRI-KL@sri-unix.UUCP Newsgroups: net.lang.prolog Subject: Equal On Terms Message-ID: <3283@sri-arpa.UUCP> Date: Mon, 18-Jul-83 11:47:20 EDT Article-I.D.: sri-arpa.3283 Posted: Mon Jul 18 11:47:20 1983 Date-Received: Fri, 22-Jul-83 20:35:42 EDT Lines: 39 An earlier message asked how to define a predicate EQUAL on two terms that didn't mind if variables were renamed but otherwise wanted the terms to be identical, thus: equal(A + B, C + D), equal(A + A, C + C) are true, but not: equal(A + A, B + C) The proposed ``quick and dirty'' solution was something like: equal(X, Y) :- assert(temp(1, X)), assert(temp(2, Y)), retract(temp(1, A)), retract(temp(2, B)), numbervars(A, 1, N), numbervars(B, 1, N), A = B. A ``better'' (I.e. faster) solution is: equal(X, Y) :- \+notequal(X, Y). notequal(X, Y) :- \+notnotequal(X, Y). notnotequal(X, Y) :- numbervars(X, 1, N), numbervars(Y, 1, N), X = Y. This is ``better'' because it doesn't use ASSERT. It's best to avoid Assert because: * It is slow - it has to copy the structure being asserted. * On the DEC-20, it consumes memory until the procedure doing the ASSERT is backtracked over - not just until the item is RETRACTed. This might be for the ENTIRE computation. A useful heuristic is that predicates that side-effect their arguments in undesirable ways (eg by using NUMBERVARS) can sometimes be rendered safe by enclosing them in a double negation. -- Steve Hardy, Teknowledge