Lab Lecture#4 Lecturer : Sheriff Nafisa TA : Mubarakah Otbi, Duaa al Ofi , Huda al Hakami In this LabLecture Matching Things Up: Unification Backtracking Visual Prolog's Relentless Search for Solutions Controlling the Search for Solution Using the fail Predicate Preventing Backtracking: The Cut Matching Things Up: Unification • When Visual Prolog tries to fulfill the goal it must test each clause in the program for a match. • Visual Prolog will search from the top of the program to the bottom. • When it finds a clause that matches the goal, it binds values to free variables so that the goal and the clause are identical; the goal is said to unify with the clause. This matching operation is called unification. Unification (contd) • Working definition: • Two terms unify if they are the same term or if they contain variables that can be uniformly instantiated with terms in such a way that the resulting terms are equal. /* Program exunify.pro */ DOMAINS title,author = symbol pages = unsigned PREDICATES book(title, pages) nondeterm written_by(author, title) nondeterm long_novel(title) CLAUSES written_by(fleming, "DR NO"). written_by(melville, "MOBY DICK"). book("MOBY DICK", 250). book("DR NO", 310). long_novel(Title):written_by(_, Title), book(Title, Length), Length > 300. written_by( X , Y ). | | written_by(fleming, "DR NO"). Visual Prolog makes a match, X becomes bound to fleming, and becomes bound to "DR NO." Visual Prolog displays first solution: X=fleming, Y=DR NO Next: written_by( X , Y ). | | written_by(melville,"MOBY DICK"). Visual Prolog displays the second solution X=melville, Y=MOBY DICK 2 Solutions give the program the goal: written_by(X, "MOBY DICK"). Visual Prolog will attempt a match with the first clause for written_by: written_by( X ,"MOBY DICK"). | | written_by(fleming,"DR NO"). Since "MOBY DICK" and "DR NO" do not match, the attempt at unification fails. Example2 vertical( line(point(X,Y), point(X,Z))). horizontal( line(point(X,Y), point(Z,Y))). ?- vertical(line(point(1,1),point(1,3))). yes ??- vertical(line(point(1,1),point(3,2))). no ?- ?- horizontal(line(point(1,1),point(1,Y))). Y = 1; No ?- horizontal(line(point(2,3),Point)). Point = point(_554,3); no ?- Backtracking • Visual Prolog uses backing-up-and-trying-again method, called backtracking, to find a solution to a given problem. • Visual Prolog begins to look for a solution to a problem (or goal), it might have to decide between two possible cases. • It sets a marker at the branching spot (known as a backtracking point) and selects the first subgoal to pursue. • If that subgoal fails (equivalent to reaching a dead end), Visual Prolog will backtrack to the back-tracking point and try an alternate subgoal. Backtracking(contd) eats(fred,pears). eats(fred,t_bone_steak). eats(fred,apples). "What are all the things that fred eats". To answer this I can use variables again. Thus I can type in the query ?- eats(fred,FoodItem). As we have seen earlier, Prolog will answer with FoodItem = pears This is because it has found the first clause in the database. At this point Prolog allows us to ask if there are other possible solutions. When we do so we get the following. FoodItem = t_bone_steak if I ask for another solution, Prolog will then give us. FoodItem = apples If we ask for further solutions, Prolog will answer no, since there are only three ways to prove fred eats something. The mechanism for finding multiple solution is called backtracking. Backtracking in Rules We can also have backtracking in rules. For example consider the following program. hold_party(X):birthday(X), happy(X). birthday(tom). birthday(fred). birthday(helen). happy(mary). happy(jane). happy(helen). If we now pose the query ?- hold_party(Who). X=helen The Four Basic Principles of Backtracking • Subgoals must be satisfied in order, from top to bottom. • Predicate clauses are tested in the order they appear in the program, from top to bottom. • When a subgoal matches the head of a rule, the body of that rule must be satisfied next. The body of the rule then constitutes a new set of subgoals to be satisfied. • A goal has been satisfied when a matching fact is found for each of the extremities (leaves) of the goal tree. Controlling the Search for Solutions • Visual Prolog provides two tools that allow you to control the backtracking mechanism: • the fail predicate, which is used to force backtracking, and • the cut (signified by !), which is used to prevent backtracking. Using the fail Predicate DOMAINS name = symbol PREDICATES nondeterm father(name, name) everybody CLAUSES father(leonard,katherine). father(carl,jason). father(carl,marilyn). everybody:father(X,Y), write(X," is ",Y,"'s father\n"), fail. everybody. The object of the predicate everybody is to produce a cleaner response from program runs. Compare the answers to the two preceding goals: Goal father(X, Y). X=leonard, Y=katherine X=carl, Y=jason X=carl, Y=marilyn 3 Solutions and Goal everybody. leonard is katherine's father carl is jason's father carl is marilyn's father Yes The predicate everybody uses backtracking to generate more solutions for father(X, Y) by forcing Prolog to backtrack through the body of the everybody rule: father(X, Y), write(X," is ",Y,"'s father\n"), fail. fail can never be satisfied (it always fails), so Visual Prolog is forced to backtrack. When backtracking takes place, Prolog backtracks to the last call that can produce multiple solutions. Such a call is labeled non-deterministic. A non-deterministic call contrasts with a call that can produce only one solution, which is a deterministic call. Preventing Backtracking: The Cut • Visual Prolog contains the cut, which is used to prevent backtracking; it's written as an exclamation mark (!). • The effect of the cut is simple: It is impossible to backtrack across a cut. • r1 :- a, b, !, c. • There are two main uses of the cut: a green cut : that certain possibilities will never give rise to meaningful solutions. a red cut : When the logic of a program demands the cut, to prevent consideration of alternate subgoals. Cut:Example PREDICATES buy_car(symbol,symbol) nondeterm car(symbol,symbol,integer) colors(symbol,symbol) CLAUSES buy_car(Model,Color):car(Model,Color,Price), colors(Color,bright),!, Price > 25000. car(maserati,green,25000). car(corvette,black,24000). car(corvette,red,26000). car(porsche,red,24000). colors(red,bright). colors(black,mean). colors(green,preppy). Given the goal: buy_car(corvette, Y) Visual Prolog calls car, the first subgoal to the buy_car predicate. It makes a test on the first car, the Maserati, which fails. It then tests the next car clauses and finds a match, binding the variable Color with the value black. It proceeds to the next call and tests to see whether the car chosen has a bright color. Black is not a bright color in the program, so the test fails. Visual Prolog backtracks to the call to car and once again looks for a Corvette to meet the criteria. It finds a match and again tests the color. This time the color is bright, and Visual Prolog proceeds to the next subgoal in the rule: the cut. The cut immediately succeeds and effectively "freezes into place" the variable bindings previously made in this clause. Visual Prolog now proceeds to the next (and final) subgoal in the rule: the comparison Price < 25000. This test fails, and Visual Prolog attempts to backtrack in order to find another car to test. Since the cut prevents backtracking, there is no other way to solve the final subgoal, and the goal terminates in failure.