• Aucun résultat trouvé

The Operation of Database Prolog

Dans le document Prolog and Natural-Language Analysis D (Page 26-29)

Intuitively, our definition of, for instance,author_ofin terms of subsidiary predicates seems correct from the logical standpoint just outlined. But how does the Prolog sys-tem make use of this predicate? Suppose we ask Prolog for the writings of Bertrand Russell with the following query:

?- author_of(bertrand, What).

What = principia yes

How does Prolog determine that a correct assignment to satisfy the goal (i.e., disprove its negation) isWhat = principia? What is the procedural interpretation of Horn clauses that Prolog uses in actually executing a goal? In this section we describe the execution of a Prolog goal informally, returning to a more precise discussion of the ex-ecution mechanism, and its relation to the logical basis for Prolog through a technique called resolution, in Section 3.5.

To execute a goal, Prolog searches forward from the beginning of the program for the first clause whose head matches the goal. We will have more to say about this matching process, called unification, when we further discuss the theory of Prolog in Section 3.5. For the time being, think of two literals matching if there exists an assignment to the variables in them under which they become identical. For instance, the literalauthor_of(bertrand, What)matches the literalauthor_of(Person,

2.4. The Operation of Database Prolog

This digital edition of Prolog and Natural-Language Analysis is distributed at no charge for noncommercial use by Microtome Publishing.

17

Book)under the assignmentPerson = bertrand, Book = What, because if the literals are modified by replacing the variables in the assignment with their assigned value, both literals becomeauthor_of(bertrand, What).

If a match is found, the selected clause is activated. The matching assignment is applied to both the goal and a copy of the clause by replacing variables with their bind-ing value, e.g., replacbind-ingPersonwithbertrandandBookwithWhat. The literals in the body of the instantiated clause (if any) are then executed in turn, from left to right.

If at any time the system fails to find a match for a goal, it backtracks, that is, it rejects the most recently activated clause, undoing any substitutions made by applying the assignment engendered by the match to the head of the clause. Next it reconsiders the original goal that activated the rejected clause, and tries to find another clause whose head also matches the goal. When finding alternative clauses, Prolog always works from the top of the program to the bottom, trying earlier clauses first.

We will trace through the operation of the system for the “writings of Russell”

example. We begin by executing the goalauthor_of(bertrand, What). Prolog finds a clause in its database whose head matches the goal. In this case, the only matching clause is

author_of(Person, Book) :-book(Book),

wrote(Person, Book).

The head of this clause matches the goal under the bindingsPerson = bertrand, Book = What as described above. Under these bindings, the body of the rule be-comesbook(What), wrote(bertrand, What). Prolog activates the clause taking this conjunction on as its new goal, executing the conjuncts one by one, working from the left to the right.

Executing book(What) requires finding a clause whose head matches it. But in this case there are two such clauses, namely the unit clauses book(begriffsschrift)andbook(principia). When faced with several clauses to choose from, Prolog chooses the textually earliest one that has not been considered in satisfying this goal; in this case, none have been considered, so the first matching clausebook(begriffsschrift)is chosen, which matches the goalbook(What) un-der the bindingWhat = begriffsschrift. Under this binding, the second conjunct iswrote(bertrand, begriffsschrift), and this becomes the next goal.

However, no clause head matches this goal, so the goal fails. Prolog backtracks to its last choice among alternative clauses. In this case, the choice was between the two unit clauses matchingbook(What). This time, in satisfying the goal, the next match-ing clause is chosen, namelybook(principia); the second conjunct then becomes wrote(bertrand, principia). This goal matches the identical unit clause in the database.

Thus we have satisfied all of the conjuncts in the antecedent of the author_of clause, thereby satisfying the original goal itself. Perusing the bindings that were necessary to satisfy the goal, we note that the variableWhatin the original goal was bound toprincipia; the bindingWhat = principiais therefore reported.

author_of(bertrand, principia)

book(principia) wrote(bertrand, principia)

Figure 2.1: A proof tree

2.4.1 Proof Trees and Traces

Often it is useful to have a method for summarizing the execution of a goal. We describe two such methods here. The first one, the proof tree, describes the literals that were proved in the course of the proof of the main goal and the dependencies between them. For the “writings of Russell” example, the main goal proved, under the satisfying assignment, wasauthor_of(bertrand, principia). It depended on the proofs of two subsidiary literals, namely,book(principia)andwrote(bertrand, principia). These literals were proved primitively with no dependent literals. Thus the proof tree for this example is as given in Figure 2.1.

This proof tree makes explicit the steps in the execution of Prolog that led to a successful proof of the goal under a given assignment. However, it abstracts away from the parts of the execution that led down blind alleys, not becoming part of the final proof. A second method of summarizing Prolog executions, the trace, is useful when this higher level of detail is desired.

The particular tracing method we shall use is called the box model (Byrd, 1980), since it models a predicate as a box with certain ports through which the computation passes. The box model underlies the tracing and debugging facilities of most Edin-burgh Prolog systems.

In a box-model trace, each step the system takes—whether it be the recursive prov-ing of a literal, the activatprov-ing of a clause to prove it, or the subsequent success or failure of the subproof—is sequentially listed using the following general format:

(i) d p: G

Each goal G is given a goal number i which uniquely identifies it throughout the ex-ecution. As the goal progresses through the execution, trace lines with the given goal number show the state of instantiation of the goal at different points. The recursion depth is given as d. The main goal has recursion depth 0, its subgoals, recursion depth 1, their subgoals, 2, and so forth.4 Trace lines correspond to different kinds of steps in the execution of a Prolog query. The port name p specifies the type of step in the execution that the trace line records. The execution of a literal is started at a Call port corresponding to the activation of the first matching clause. When the proof using this clause is successful, a trace line with the port name Exit is listed. If the first clause activated does not yield a successful proof, a Redo port line is added for each later clause that is invoked. Finally, if all clauses fail to provide a proof for the given goal, a Fail port trace line is used.

4We will also sometimes use indentation to reflect the depth of recursion of the execution in order to aid readability.

Dans le document Prolog and Natural-Language Analysis D (Page 26-29)