[unify:UnifyHandler, test_unify:TUHandler, ...]Handlers for operations which are not specified or those that are true/0 are ignored and never invoked. If Name is an existing extension, the specified handlers replace the current ones.
Whenever one of the specified operations detects an attributed variable, it will invoke all handlers that were declared for it and each of them receives either the whole attributed variable or its particular attribute as argument. The system does not check if the attribute that corresponds to a given handler is instantiated or not; this means that the handler must check itself if the attributed variable contains any attribute information or not. For instance, if an attributed variable X{a:_, b:_, c:f(a)} is unified with the attributed variable Y{a:_, b:_, c:f(b)}, the handlers for the attributes a and b should treat this as binding of two plain variables because their attributes were not involved. Only the handler for c has any work to do here. The library suspend.pl can be used as a template for writing attributed variable handlers.
The following operations invoke attributed variable handlers:
unify_handler(+Term, ?Attribute)The first argument is the term that was unified with the attributed variable, it is either a nonvariable or an attributed variable. The second argument is directly the contents of the attribute slot corresponding to the extension, i.e. it is not the whole attributed variable. When this handler is invoked, the attributed variable is already bound to Term.
If an attributed variable is unified with a standard variable, the variable is bound to the attributed variable and no handlers are invoked. If an attributed variable is unified with another attributed variable or a non-variable, the attributed variable is bound (like a standard variable) to the other term and all handlers for the unify operation are invoked. Note that several attributed variable bindings can occur e.g. during a head unification and also during a single unification of compound terms. The handlers are only invoked at certain trigger points (usually before the next predicate call).
pre_unify_handler(?AtrVar, +Term)The first argument is the attributed variable to be unfied, the second argument is the term it is going to be unified with. This handler is provided only for compatibility with SICStus Prolog and its use is not recommended, because it is less efficient than the unify handler and because its semantics is not quite clean, there may be cases where changes inside this handler may have unexpected effects.
test_unify_handler(+Term, ?Attribute)where the arguments are the same as for the unify handler. During the execution of the handler the attributed variable is bound to Term, however when all local handlers succeed, all bindings are undone.
instance_handler(-Res, ?TermL, ?TermR)and its arguments are similar to the compare_instances/3 predicate. Res is the relation between the two terms TermL and TermR, it can be either = or < (the handler might directly fail if the result is >). All bindings made in the handler will be undone after processing the local handlers.
copy_handler(?Meta, ?Var)Meta is the attributed variable encountered in the copied term, Var is its corresponding variable in the copy. All extension handlers receive the same arguments. This means that if the attributed variable should be copied as an attributed variable, the handler must check if Var is still a free variable or if it was already bound to an attributed variable by a previous handler.
delayed_goals_handler(?Meta, ?GoalList, -GoalCont)Meta is the attributed variable encountered in the term, GoalList is an open-ended list of all delayed goals in this attribute and GoalCont is the tail of this list.
delayed_goals_number_handler(?Meta, -Number)Meta is the attributed variable encountered in the term, Number is the number of delayed goals occurring in this attribute. Its main purpose is for the first-fail selection predicates, i.e. it should return the number of constraints imposed on the variable.
print_handler(?AttrVar, -Attribute)AttrVar is the attributed variable being printed, Attribute is the term which will be printed as a value for this attribute, prefixed by the attribute name. If no handler is specified for an attribute, it will not be printed.
X{Attr}where Attr is the value obtained from the handler. If there are several handled attributes, all attributes are qualified like in
X{a:A, b:B, c:C}.An attributed variable X{m:a} with print handler =/2 can thus be printed in different ways, e.g.: 16.2
printf("%w", [X{m:a}]) or write(X{m:a}): X printf("%vMw", [X{m:a}]) or writeq(X{m:a}): _g246{suspend : _g242, m : a} printf("%mw", [X{m:a}]): X{a} printf("%Mw", [X{m:a}]): X{suspend : _g251, m : a} printf("%Vmw", [X{m:a}]): X_g252{a}
Write macros for attributed variables are not allowed because one extension alone should not decide whether the other attributes will be printed or not.