• Aucun résultat trouvé

A Classification of Metalevel Systems

Meta-Interpretation

8.5 A Classification of Metalevel Systems

Drawing on the discussion above, we can now attempt a classification of metalevel systems. The classification is based on that suggested by van Harmelen [1991]. The first class of metalevel systems may be termed definitional and uses a metalanguage in order to define another language. This may be purely in order to give a semantics, which is operational if the metalanguage is executable, but it may also be part of a practical implementation. Symbolic processing languages are particularly suited to implementing other languages. In artificial intelligence, building a higher-level knowledge-representation language on top of a lower-level declarative language is a common practice, recommended in textbooks on artificial intelligence programming in both Lisp [Charniak et al., 1987] and Prolog [Bratko, 1986].

A second class may be termed enhanced metacircular interpreters. In this class the metalanguage is the same as the object language and the purpose of the interpreter is to provide an additional output alongside the interpretation. Among the additional outputs that can be provided are certainty factors for use in expert systems applications [Shapiro, 1983] and computation trees for use in debugging [Huntbach, 1987]. The chapter on meta-interpreters in Sterling and Shapiro’s Prolog textbook [Sterling and Shapiro, 1986] is largely confined to this sort of meta-interpreter and provides numerous examples. Use of this sort of meta-interpreter occurs mainly among logic programmers because they are easy to write in logic languages: complex issues like control and variable handling are simply passed implicitly from object level to metalevel to the underlying system.

The most varied class of metalevel systems, however, is that class of systems where the aim is to separate control issues from declarative issues, but to provide the ability to program both. This follows from Kowalski’s [1979] dictum “Algorithm = Logic + Control.” Multiple layers of meta-interpreters means that it is possible to break down control into metalogic and metacontrol and so on.

It might be possible to alter the flow of control in some procedural languages, but in general these languages are such that logic and control are so intertwined as to be inseparable. Declarative languages, however, are built around the idea that control is left to the underlying system and the program is simply a declaration of the possible set of solutions. This opens the question as to why the programmer should have any control over control, since it is just an implementation detail. There is, however, a group of languages that are neither procedural nor declarative. As suggested above, production rule systems fall into this group and are the paradigm in which the issue of metalevel control first received practical attention.

The reason why control arises as an issue in declarative languages is the question of efficiency. In functional languages the only control issue is reduction order. The Church–Rosser theorem [Barendregt, 1984] tells us that if it terminates, whatever way we reduce a functional expression we will get the same result. It is possible for one reduction order to return a result quicker than another is, or for one reduction order to return a result while another does not terminate. Additional questions of efficiency arise when implementing a functional language on a multi-processor system when a decision has to be made as to whether the overhead of moving a subexpression to another processor to be evaluated in parallel is outweighed by the benefits of parallel execution. These considerations have led to suggestions for simple control annotations controlling reduction order and parallel processing in functional languages [Burton, 1987].

In logic languages, there is greater scope for order of reduction to affect efficiency.

Whereas in a functional language control is generally considered something for the system to sort out, in logic languages there have been many proposals for methods to give the user control over control. Smith and Genesereth [1985] analyze in detail the effect that the ordering of conjunctive queries can have. The practical Prolog programmer always has to be aware of Prolog’s left-to-right reduction order, writing programs such that the optimal ordering of queries matches this built-in order.

However, the optimal order may only be determinable at run-time and often depends on the mode in which a predicate is called. The lack of ability to change query order dynamically is one of the reasons why Prolog’s multi-mode facility is rarely useful in any but trivial programs. Metalevel annotations to give the programmer control over query order were among the earliest suggestions to improve Prolog [Clark et al., 1982; Colmerauer et al., 1982]. Cohen [1985] gives a metacircular interpreter to implement Prolog II’s freeze. This is a metalevel procedure where freeze(X,G) with X a variable and G a goal causes G to be removed from the list of goals waiting for execution if X is unbound, but to be placed at the head of it as soon as X becomes bound. Owen [1988] gives a metacircular interpreter that was used to allow flexible goal ordering, which was used in the domain of protein topology. As we have seen, in GDC there is a built-in suspension mechanism which works in a similar way to

freeze and otherwise obviates the need for further goal ordering mechanisms until we consider the speculative computation issues in Chapter 6.

Van Harmelen classifies metalevel systems on the basis on combinatorial soundness and completeness. A metalevel inference system is combinatorially complete if it derives all results derivable from the object level theory and combinatorially sound if it derives only results derivable from the object level theory. Goal re-ordering will not affect the soundness or completeness of a logic program (except that it may make solutions obtainable that would be unobtainable due to being beyond infinite branches). Metarules that prune the search tree by cutting out some clauses from being considered will make a metalevel system incomplete, which is not a problem in GDC, as it does not attempt to be complete. The unknown test in a guard is an example of a metalevel feature that prunes the results possible. Prolog’s assert is an example of a metalevel feature that introduces unsoundness. The distinction commonly made in Prolog between “red cuts” and “green cuts” distinguishes those usages of cut which affect the completeness of a Prolog program and those usages where the cut is used purely to cut out search, which the programmer knows will not lead to solutions and thus will not affect the completeness. The red/green distinction could usefully be extended to other extra-logical notations: usages that affect the soundness or completeness being termed red, those which do not being termed green.

A green assert in Prolog, for example, would be one which simply asserts a lemma for efficiency reasons that could be proved form the existing clauses for the predicate.

A useful general rule in considering proposed metalevel control annotations would be to accept only those that are capable of just green use.

Van Harmelen’s main classification of metalevel systems, however, concerns the locus of action: the place in which the system is active at any one point in time. A metalevel system with object-level inference is one where the main activity is in the object-level interpreter. This covers those systems where the metalevel interpreter is implicit and programmer control over it is limited to annotations, such as the various examples above of Prolog control languages. A metalevel system with metalevel inference is one where the computation takes place mainly in the metalevel interpreter. This covers those systems where a full interpreter is available for inspection and modification, and the attention is on this interpreter manipulating the object-level program. An intermediate class covers those systems where the locus of action shifts between the object-level and the metalevel. An example of the intermediate class is those production systems where control jumps to the metalevel for conflict resolution. In parallel logic programming, Pandora [Bahgat and Gregory, 1989] is an example of a mixed-level inference system. It behaves in a similar way to the concurrent logic languages, but if it hits a deadlock, control jumps to a metalevel deadlock handler [Bahgat, 1992] which resolves the situation by making a non-deterministic choice.

The final distinction that van Harmelen makes is to distinguish between monolingual and bilingual metalevel systems. A monolingual system is one where the language at the metalevel is the same as at the object-level, in particular object-level variables are mapped into metalevel variables. A bilingual system is one where the object-level and metalevel languages are distinct, in particular object-level variables are

represented by ground terms at the metalevel. Van Harmelen argues strongly in favor of bilingual systems on the grounds of clarity. The argument is both informal, considering the practical and conceptual difficulties of mixing the two levels, and formal, after Hill and Lloyd’s analysis [1988] which suggested that semantics for metalevel programs could not be derived while there was a confusion between metalevel and object-level variables. Hill and Lloyd followed this by introducing a logic language, Gödel [Hill and Lloyd, 1994], in which there are built-in object-level and metalevel variables, with predicates at the metalevel operating on object-level variables which replace the extra-logical predicates of Prolog. The counter-argument is the simplicity of monolingual interpreters due to not having to make explicit that which they do not change from the underlying system. Martens and de Schreye [1995] argue that it is possible to come up with a formal semantics for monolingual systems.