micha@ecrc.de (Micha Meier) (06/13/91)
Several people have asked me if Sepia, which is claimed to be an extensible Prolog system, allows the user to redefine the unification. Until the version 3.0.15 this was possible only with sources (although easily :-)). In the new release I have included a new data type - metaterms. A metaterm is basically an atributed variable, like the one proposed e.g. by U.Neumerkel (metastructure) or S. Le Huitouze (vara). The metaterms in Sepia have been implemented using the coroutining and event mechanisms. A metaterm looks like a normal variable, but it has an attribute, which can be any Prolog term (even another metaterm) and which can be accessed from it. Whenever the system tries to instantiate a metaterm or to bind it to another metaterm, an event is raised and the result of the binding is specified by a user-defined event handler. Similarly, if a metaterm occurs in a built-in predicate, another event is raised. In the event handler, the user can e.g. inspect the attribute of the metaterm and modify it, or the metaterm variable can be instantiated to some value, discarding the attribute, etc. In this way, the user has a generic datatype whose processing is completely specified by her/him. There are many ways of using metaterms, we are just starting to recognize their full potential. For example, variables whose values range over a specified domain can be represented as metaterms, their attribute being the list of the admissible values for the variable. When two variables are unified, the handler makes the instersection of the two domains and if there is only one element left, it instantiates them: [sepia]: [user]. meta_meta_unify(A, B) :- meta_term(A, DA), % DA is the attribute of A meta_term(B, DB), intersection(DA, DB, DC), % compute the intersection of the two domains (DC = [Val] -> % only one value possible, bind the two variables meta_bind(A, Val), % discard the attribute and bind the variable meta_bind(B, Val) ; meta_term(C, DC), % create a new metaterm meta_bind(A, C), % and bind the two variables to it meta_bind(B, C) ). user compiled traceable 608 bytes in 0.02 seconds yes. % 10 is the event of unifying two metaterms [sepia]: set_error_handler(10, meta_meta_unify/2). yes. [sepia]: meta_term(A, [yellow, blue, white, green]), meta_term(B, [orange, blue, red, yellow]), A = B. A = <C-[yellow, blue]> % the metaterm is printed using portray/2 B = <C-[yellow, blue]> yes. [sepia]: meta_term(A, [yellow, blue, white, green]), meta_term(B, [orange, blue, red, black]), A = B. A = blue B = blue yes. When, on the other hand, the variable is being instantiated, the event handler checks if the value is permitted, and if so, it instantiates it: [sepia]: [user]. meta_term_unify(Meta, Term) :- meta_term(Meta, Type), memberchk(Term, Type), meta_bind(Meta, Term). user compiled traceable 216 bytes in 0.00 seconds yes. % 11 is the event of unifying a metaterm with a nonvariable [sepia]: set_error_handler(11, meta_term_unify/2). yes. [sepia]: meta_term(A, [yellow, blue, red]), A = red. A = red yes. [sepia]: meta_term(A, [white, lila, pink, grey]), A = blue. no (more) solution. There are various possible uses for metaterms: - A static attribute of a variable. An example is the source name of the variable (in Sepia the source names are kept using the same mechanism, but more directly). - A dynamic attribute - e.g. a list of goals that have to be executed when the variable becomes (more) instantiated. Typically, coroutining can be implemented on top of metaterms. - Generic data types with run-time type testing, like the example above. - Constraint propagation. The attribute can represent the domain of the variable and a list of constraints to be evaluated when the domain is updated. For example, constraint propagation over finite domains can be very easily implemented by representing the domain as a list of values (or numeric intervals), and constraints can be suspended using the normal delaying mechanism of Sepia. - A term which contains metaterms can be seen as a potential representation of many other terms (instances) and depending on the context where it is used, it is interpreted as the corresponding one. For example, when mixing a metaprogram with the object program, there are usually some difficulties as to how to represent the object variables. If they are metaterms, they can be treated as ground terms by the metaprogram and as variables in reflection to the object level. It is also important to note that there is no performance penalty when not using the metaterms, and processing the metaterms themselves is also quite efficient, because the underlying WAM of Sepia has been written with similar extensions in mind. Sepia, which is a complete, compiler-based Unix Prolog system, includes various other advanced features, including a high-level debugging tool Opium, graphics, C interface and extensive documentation. ECRC will be demonstrating Sepia and other interesting systems at the ICLP'91 exhibition in Paris. --Micha E-MAIL micha@ecrc.de MAIL Micha Meier Tel. +49-89-92699-108 ECRC, Arabellastr. 17 Fax +49-89-92699-170 8000 Munich 81 Germany -- E-MAIL micha@ecrc.de MAIL Micha Meier Tel. +49-89-92699-108 ECRC, Arabellastr. 17 Fax +49-89-92699-170 8000 Munich 81 Germany