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, WarwickReceived 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