Diagram showing how to think about the structure involved
The diagram explains what's going on in this application of attributed variables, where the attribute values are ordsets and unification means the new attribute value is the intersection of the ordsets.
(And that's all there is to it.)
Matrix showing when
attr_unif_hook is triggered
The different cases are also tested in
Rewritten example code
The example given is too compressed for me.
Here is the example rewritten for more clarity (IMHO) and with lots of more comments, and debug printouts and separate
set predicates for the attribute in question (... awkwardly shoehorning an imperative
set into a single predicate
domain/2, as done in the example, is just a step too far for me). Additionally, the hook predicate updates a global variable to indicate that it has been called (and with what arguments), so that test cases can easily verify that it has, indeed, been called, and that it has been called only once.
- Test cases:
enum_domain.plt(note that Github won't correctly syntax-highlight .plt files, it thinks those are gnuplot files)
Example code subtlety
The example application has a subtle unfelicity (with no deleterious consequences) in that the unification
Y = Value assigns one of the allowed values for attribute
domain (held in Value) to an unbound variable (Y) that itself carries the attribute
domain. This works but needlessly triggers itself a call to
attr_unify_hook/2 from within
attr_unif_hook/2. One would need to to remove attribute
domain from Y first.