Re:

From: Warwick Harvey <wh_at_icparc.ic.ac.uk>
Date: Thu 10 May 2001 03:43:31 PM GMT
Message-ID: <3AFAB723.CFC5DD94@icparc.ic.ac.uk>
Hi,

I also meant to say that I recommend you avoid doing output unifications
in the heads of clauses with cuts in them, unless you're absolutely 100%
certain the predicate will only ever be called with a completely free
variable for that argument.  E.g. I'd rewrite your predicate to look
more like this:

agrege_prefs(_, [], C, Out) :-
  !,
  Out = C.
agrege_prefs(A, C, [], Out) :-
  atom(A),
  !,
  Out = [[A | C]].
agrege_prefs(A, C, [], Out) :-
  list(A),
  !,
  fd:(M::A),
  Out = [[M | C]].
agrege_prefs(U, New, [[U|Old]|Rest], Out) :-
  true,		% Avoid compiler bug
  !,
  append(New, Old, All),
  Out = [[U | All] | Rest].
agrege_prefs(U, New, [X|Rest], [X|Next]) :-
  agrege_prefs(U, New, Rest, Next).

Why?  Consider the goal:

  agrege_prefs(c, [], [], Out), Out = [[c]].

This matches the first clause, resulting in Out being bound to [], which
then fails to unify with [[c]] --- the goal as a whole fails.  However,
the following goal, which logically should be equivalent, succeeds
(because it doesn't match the first clause, but does match the second):

  agrege_prefs(c, [], [], [[c]]).

That's nasty.  But if you move the output unifications to after the cuts
(as above), then both goals are indeed equivalent (they both fail).

Cheers,
Warwick
Received on Thu May 10 16:43:33 2001

This archive was generated by hypermail 2.1.8 : Wed 16 Nov 2005 06:08:06 PM GMT GMT